From 6a1a22825bc33d89033176d229736e105a136f42 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 12 Feb 2012 00:06:52 -0500 Subject: [PATCH 001/527] Working proof of concept of spec tag --- imagekit/__init__.py | 2 + imagekit/base.py | 94 ++++++++++++++++++++++++ imagekit/templatetags/__init__.py | 1 + imagekit/templatetags/imagekit_tags.py | 99 ++++++++++++++++++++++++++ 4 files changed, 196 insertions(+) create mode 100644 imagekit/base.py create mode 100644 imagekit/templatetags/__init__.py create mode 100644 imagekit/templatetags/imagekit_tags.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 1b2a4a33..d19b0f14 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -2,3 +2,5 @@ __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' __version__ = (1, 1, 0, 'final', 0) __license__ = 'BSD' + +from .base import * diff --git a/imagekit/base.py b/imagekit/base.py new file mode 100644 index 00000000..2fc3d652 --- /dev/null +++ b/imagekit/base.py @@ -0,0 +1,94 @@ +import os + +from django.core.files.images import ImageFile +from django.db.models.fields.files import ImageFieldFile + +from .imagecache import get_default_image_cache_backend +from .generators import SpecFileGenerator +from .processors import ProcessorPipeline, AutoConvert + + +def autodiscover(): + """ + Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when + not present. This forces an import on them to register any admin bits they + may want. + + Copied from django.contrib.admin + """ + + import copy + from django.conf import settings + from django.utils.importlib import import_module + from django.utils.module_loading import module_has_submodule + from .templatetags import imagekit_tags + + for app in settings.INSTALLED_APPS: + mod = import_module(app) + # Attempt to import the app's admin module. + try: + import_module('%s.imagespecs' % app) + except: + # Decide whether to bubble up this error. If the app just + # doesn't have an admin module, we can ignore the error + # attempting to import it, otherwise we want it to bubble up. + if module_has_submodule(mod, 'imagespecs'): + raise + + +class ImageSpec(object): + def __init__(self, *args, **kwargs): + self._args = args + self._kwargs = kwargs + + def get_file(self, source_file, spec_id): + return ImageSpecFile(source_file, spec_id, *self._args, **self._kwargs) + self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \ + or get_default_image_cache_backend() + + +class ImageSpecFile(ImageFieldFile): + def __init__(self, source_file, spec_id, processors=None, format=None, options={}, + autoconvert=True, storage=None, cache_state_backend=None): + self.generator = SpecFileGenerator(processors=processors, + format=format, options=options, autoconvert=autoconvert, + storage=storage) + self.storage = storage or source_file.storage + self.cache_state_backend = cache_state_backend or \ + get_default_cache_state_backend() + self.source_file = source_file + self.spec_id = spec_id + + @property + def url(http://github.com/self): + self.validate() + return super(ImageFieldFile, self).url + + def _get_file(self): + self.validate() + return super(ImageFieldFile, self).file + + file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file) + + def clear(self): + return self.cache_state_backend.clear(self) + + def invalidate(self): + return self.cache_state_backend.invalidate(self) + + def validate(self): + return self.cache_state_backend.validate(self) + + @property + def name(self): + source_filename = self.source_file.name + filepath, basename = os.path.split(source_filename) + filename = os.path.splitext(basename)[0] + extension = self.generator.suggest_extension(source_filename) + new_name = '%s%s' % (filename, extension) + cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ + [filepath, new_name] + return os.path.join(*cache_filename) + + def generate(self, save=True): + return self.generator.generate_file(self.name, self.source_file, save) diff --git a/imagekit/templatetags/__init__.py b/imagekit/templatetags/__init__.py new file mode 100644 index 00000000..e0a23fc0 --- /dev/null +++ b/imagekit/templatetags/__init__.py @@ -0,0 +1 @@ +from .imagekit_tags import spec diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py new file mode 100644 index 00000000..c9d6f558 --- /dev/null +++ b/imagekit/templatetags/imagekit_tags.py @@ -0,0 +1,99 @@ +from django import template +import os + +register = template.Library() + + +class AlreadyRegistered(Exception): + pass + + +class NotRegistered(Exception): + pass + + +class SpecRegistry(object): + def __init__(self): + self._specs = {} + + def register(self, id, spec): + if id in self._specs: + raise AlreadyRegistered('The spec with id %s is already registered' % id) + self._specs[id] = spec + + def unregister(self, id, spec): + try: + del self._specs[id] + except KeyError: + raise NotRegistered('The spec with id %s is not registered' % id) + + def get_spec(self, id): + try: + return self._specs[id] + except KeyError: + raise NotRegistered('The spec with id %s is not registered' % id) + + +spec_registry = SpecRegistry() + + +class SpecNode(template.Node): + def __init__(self, spec_id, source_image, variable_name): + self.spec_id = spec_id + self.source_image = source_image + self.variable_name = variable_name + + def _default_cache_to(self, instance, path, specname, extension): + """ + Determines the filename to use for the transformed image. Can be + overridden on a per-spec basis by setting the cache_to property on + the spec. + + """ + filepath, basename = os.path.split(path) + filename = os.path.splitext(basename)[0] + new_name = '%s_%s%s' % (filename, specname, extension) + return os.path.join(os.path.join('cache', filepath), new_name) + + def render(self, context): + spec_id = self.spec_id.resolve(context) + spec = spec_registry.get_spec(spec_id) + source_image = self.source_image.resolve(context) + variable_name = str(self.variable_name) + context[variable_name] = spec.get_file(source_image, spec_id) + return '' + + +#@register.tag +def spec(parser, token): + """ + Creates an image based on the provided spec and source image and sets it + as a context variable: + + {% spec 'myapp:thumbnail' mymodel.profile_image as th %} + + + """ + + args = token.split_contents() + + if len(args) != 5 or args[3] != 'as': + raise TemplateSyntaxError('\'spec\' tags must be in the form "{% spec spec_id image as varname %}"') + + return SpecNode(*[parser.compile_filter(arg) for arg in args[1:3] \ + + [args[4]]]) + + +spec = spec_tag = register.tag(spec) + + +def _register_spec(id, spec): + spec_registry.register(id, spec) + + +def _unregister_spec(id, spec): + spec_registry.unregister(id, spec) + + +spec_tag.register = _register_spec +spec_tag.unregister = _unregister_spec From 807beef4180c8eda60015674fc9f7c9fa1c5d810 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 12 Feb 2012 16:00:43 -0500 Subject: [PATCH 002/527] Centralized spec properies --- imagekit/base.py | 40 +++++++++++++++----------- imagekit/templatetags/imagekit_tags.py | 12 +++++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/imagekit/base.py b/imagekit/base.py index 2fc3d652..b6865d72 100644 --- a/imagekit/base.py +++ b/imagekit/base.py @@ -36,26 +36,32 @@ def autodiscover(): raise -class ImageSpec(object): - def __init__(self, *args, **kwargs): - self._args = args - self._kwargs = kwargs +class SpecWrapper(object): + """ + Wraps a user-defined spec object so we can access properties that don't + exist without errors. - def get_file(self, source_file, spec_id): - return ImageSpecFile(source_file, spec_id, *self._args, **self._kwargs) + """ + def __init__(self, spec): + self.processors = getattr(spec, 'processors', None) + self.format = getattr(spec, 'format', None) + self.options = getattr(spec, 'options', None) + self.autoconvert = getattr(spec, 'autoconvert', True) + self.storage = getattr(spec, 'storage', None) self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \ or get_default_image_cache_backend() class ImageSpecFile(ImageFieldFile): - def __init__(self, source_file, spec_id, processors=None, format=None, options={}, - autoconvert=True, storage=None, cache_state_backend=None): - self.generator = SpecFileGenerator(processors=processors, - format=format, options=options, autoconvert=autoconvert, - storage=storage) - self.storage = storage or source_file.storage - self.cache_state_backend = cache_state_backend or \ - get_default_cache_state_backend() + def __init__(self, spec, source_file, spec_id): + spec = SpecWrapper(spec) + + self.storage = spec.storage or source_file.storage + self.generator = SpecFileGenerator(processors=spec.processors, + format=spec.format, options=spec.options, + autoconvert=spec.autoconvert, storage=self.storage) + + self.spec = spec self.source_file = source_file self.spec_id = spec_id @@ -71,13 +77,13 @@ def _get_file(self): file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file) def clear(self): - return self.cache_state_backend.clear(self) + return self.spec.image_cache_backend.clear(self) def invalidate(self): - return self.cache_state_backend.invalidate(self) + return self.spec.image_cache_backend.invalidate(self) def validate(self): - return self.cache_state_backend.validate(self) + return self.spec.image_cache_backend.validate(self) @property def name(self): diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index c9d6f558..c8069a80 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,5 +1,7 @@ -from django import template import os +from django import template +from .. import ImageSpecFile + register = template.Library() @@ -56,11 +58,13 @@ def _default_cache_to(self, instance, path, specname, extension): return os.path.join(os.path.join('cache', filepath), new_name) def render(self, context): - spec_id = self.spec_id.resolve(context) - spec = spec_registry.get_spec(spec_id) source_image = self.source_image.resolve(context) variable_name = str(self.variable_name) - context[variable_name] = spec.get_file(source_image, spec_id) + spec_id = self.spec_id.resolve(context) + spec = spec_registry.get_spec(spec_id) + if callable(spec): + spec = spec() + context[variable_name] = ImageSpecFile(spec, source_image, spec_id) return '' From d275aaa3f70ad8103cb3068ac7a7dcd75237a990 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 13 Feb 2012 22:05:33 -0500 Subject: [PATCH 003/527] A little reorganization --- imagekit/__init__.py | 2 -- imagekit/{base.py => files.py} | 48 +------------------------- imagekit/templatetags/imagekit_tags.py | 3 +- imagekit/utils.py | 47 ++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 51 deletions(-) rename imagekit/{base.py => files.py} (50%) diff --git a/imagekit/__init__.py b/imagekit/__init__.py index d19b0f14..1b2a4a33 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -2,5 +2,3 @@ __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' __version__ = (1, 1, 0, 'final', 0) __license__ = 'BSD' - -from .base import * diff --git a/imagekit/base.py b/imagekit/files.py similarity index 50% rename from imagekit/base.py rename to imagekit/files.py index b6865d72..ddfa4a8f 100644 --- a/imagekit/base.py +++ b/imagekit/files.py @@ -1,55 +1,9 @@ import os -from django.core.files.images import ImageFile from django.db.models.fields.files import ImageFieldFile -from .imagecache import get_default_image_cache_backend from .generators import SpecFileGenerator -from .processors import ProcessorPipeline, AutoConvert - - -def autodiscover(): - """ - Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when - not present. This forces an import on them to register any admin bits they - may want. - - Copied from django.contrib.admin - """ - - import copy - from django.conf import settings - from django.utils.importlib import import_module - from django.utils.module_loading import module_has_submodule - from .templatetags import imagekit_tags - - for app in settings.INSTALLED_APPS: - mod = import_module(app) - # Attempt to import the app's admin module. - try: - import_module('%s.imagespecs' % app) - except: - # Decide whether to bubble up this error. If the app just - # doesn't have an admin module, we can ignore the error - # attempting to import it, otherwise we want it to bubble up. - if module_has_submodule(mod, 'imagespecs'): - raise - - -class SpecWrapper(object): - """ - Wraps a user-defined spec object so we can access properties that don't - exist without errors. - - """ - def __init__(self, spec): - self.processors = getattr(spec, 'processors', None) - self.format = getattr(spec, 'format', None) - self.options = getattr(spec, 'options', None) - self.autoconvert = getattr(spec, 'autoconvert', True) - self.storage = getattr(spec, 'storage', None) - self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \ - or get_default_image_cache_backend() +from .utils import SpecWrapper class ImageSpecFile(ImageFieldFile): diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index c8069a80..202118f8 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,6 +1,7 @@ import os from django import template -from .. import ImageSpecFile + +from ..files import ImageSpecFile register = template.Library() diff --git a/imagekit/utils.py b/imagekit/utils.py index 305bdd44..4f695cfd 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -4,7 +4,8 @@ from django.db.models.loading import cache from django.utils.functional import wraps -from imagekit.lib import Image, ImageFile +from .imagecache import get_default_image_cache_backend +from .lib import Image, ImageFile def img_to_fobj(img, format, **kwargs): @@ -165,3 +166,47 @@ def validate_app_cache(apps, force_revalidation=False): if force_revalidation: f.invalidate() f.validate() + + +def autodiscover(): + """ + Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when + not present. This forces an import on them to register any admin bits they + may want. + + Copied from django.contrib.admin + """ + + import copy + from django.conf import settings + from django.utils.importlib import import_module + from django.utils.module_loading import module_has_submodule + from .templatetags import imagekit_tags + + for app in settings.INSTALLED_APPS: + mod = import_module(app) + # Attempt to import the app's admin module. + try: + import_module('%s.imagespecs' % app) + except: + # Decide whether to bubble up this error. If the app just + # doesn't have an admin module, we can ignore the error + # attempting to import it, otherwise we want it to bubble up. + if module_has_submodule(mod, 'imagespecs'): + raise + + +class SpecWrapper(object): + """ + Wraps a user-defined spec object so we can access properties that don't + exist without errors. + + """ + def __init__(self, spec): + self.processors = getattr(spec, 'processors', None) + self.format = getattr(spec, 'format', None) + self.options = getattr(spec, 'options', None) + self.autoconvert = getattr(spec, 'autoconvert', True) + self.storage = getattr(spec, 'storage', None) + self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \ + or get_default_image_cache_backend() From 722a5535011a2fd5f42bdcd9391abbe15dd83114 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 13 Feb 2012 22:12:34 -0500 Subject: [PATCH 004/527] Automatically autodiscover --- imagekit/templatetags/imagekit_tags.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 202118f8..92eefb5d 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -59,6 +59,8 @@ def _default_cache_to(self, instance, path, specname, extension): return os.path.join(os.path.join('cache', filepath), new_name) def render(self, context): + from ..utils import autodiscover + autodiscover() source_image = self.source_image.resolve(context) variable_name = str(self.variable_name) spec_id = self.spec_id.resolve(context) From 938acedcc7b5852da30b53c77fa52be01b4c9eda Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 13 Feb 2012 22:13:32 -0500 Subject: [PATCH 005/527] Decorator syntax for registering specs --- imagekit/templatetags/imagekit_tags.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 92eefb5d..0cb21ed1 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -94,7 +94,12 @@ def spec(parser, token): spec = spec_tag = register.tag(spec) -def _register_spec(id, spec): +def _register_spec(id, spec=None): + if not spec: + def decorator(cls): + spec_registry.register(id, cls) + return cls + return decorator spec_registry.register(id, spec) From f438f63bf8fea9507ce50015f64f81d7106657f6 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sat, 28 Apr 2012 11:30:09 -0700 Subject: [PATCH 006/527] Changelog update. --- docs/changelog.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 92578700..34d3ef73 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,12 @@ Changelog ========= +v2.0.1 +------ + +- Fixed a file descriptor leak in the `utils.quiet()` context manager. + + v2.0.0 ------ From 78a9018337771cdded6ab8894d6437fcc105f347 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sat, 28 Apr 2012 11:31:25 -0700 Subject: [PATCH 007/527] Bumping the version number. --- docs/conf.py | 4 ++-- imagekit/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1ba36ca6..580401c8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -50,9 +50,9 @@ # built documents. # # The short X.Y version. -version = '2.0.0' +version = '2.0.1' # The full version, including alpha/beta/rc tags. -release = '2.0.0' +release = '2.0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/imagekit/__init__.py b/imagekit/__init__.py index d525af21..55a5d048 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,6 +1,6 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = (2, 0, 0, 'final', 0) +__version__ = (2, 0, 1, 'final', 0) __license__ = 'BSD' From 7ad5cf4db5cfb674bd53968cd00eba4b85e85f71 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 19 Jul 2012 21:53:50 -0400 Subject: [PATCH 008/527] Use hashes for generated image filenames While this change means users can no longer specify their own filenames, changing a property of a processor, for example, will now result in a new image. This solves a lot of the previous invalidation issues. --- imagekit/conf.py | 1 + imagekit/generators.py | 34 ++++++++++++++++++--- imagekit/models/fields/__init__.py | 20 ++---------- imagekit/models/fields/files.py | 49 ++---------------------------- 4 files changed, 35 insertions(+), 69 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 51ddf558..4f3b95c1 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,3 +3,4 @@ class ImageKitConf(AppConf): DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend' + CACHE_DIR = 'CACHE/images' diff --git a/imagekit/generators.py b/imagekit/generators.py index 046f0c07..344fc672 100644 --- a/imagekit/generators.py +++ b/imagekit/generators.py @@ -1,8 +1,11 @@ +from django.conf import settings +from hashlib import md5 import os +import pickle from .lib import StringIO from .processors import ProcessorPipeline from .utils import (img_to_fobj, open_image, IKContentFile, extension_to_format, - UnknownExtensionError) + suggest_extension, UnknownExtensionError) class SpecFileGenerator(object): @@ -14,14 +17,18 @@ def __init__(self, processors=None, format=None, options=None, self.autoconvert = autoconvert self.storage = storage + def get_processors(self, source_file): + processors = self.processors + if callable(processors): + processors = processors(source_file) + return processors + def process_content(self, content, filename=None, source_file=None): img = open_image(content) original_format = img.format # Run the processors - processors = self.processors - if callable(processors): - processors = processors(source_file) + processors = self.get_processors(source_file) img = ProcessorPipeline(processors or []).process(img) options = dict(self.options or {}) @@ -42,6 +49,25 @@ def process_content(self, content, filename=None, source_file=None): content = IKContentFile(filename, imgfile.read(), format=format) return img, content + def generate_filename(self, source_file): + source_filename = source_file.name + filename = None + if source_filename: + hash = md5(''.join([ + pickle.dumps(self.get_processors(source_file)), + self.format, + pickle.dumps(self.options), + str(self.autoconvert), + ])).hexdigest() + extension = suggest_extension(source_filename, self.format) + + filename = os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (hash, extension))) + + return filename + def generate_file(self, filename, source_file, save=True): """ Generates a new image file by processing the source file and returns diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index b2cceda1..faa5fb58 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -17,8 +17,8 @@ class ImageSpecField(object): """ def __init__(self, processors=None, format=None, options=None, - image_field=None, pre_cache=None, storage=None, cache_to=None, - autoconvert=True, image_cache_backend=None): + image_field=None, pre_cache=None, storage=None, autoconvert=True, + image_cache_backend=None): """ :param processors: A list of processors to run on the original image. :param format: The format of the output file. If not provided, @@ -33,21 +33,6 @@ def __init__(self, processors=None, format=None, options=None, original image. :param storage: A Django storage system to use to save the generated image. - :param cache_to: Specifies the filename to use when saving the image - cache file. This is modeled after ImageField's ``upload_to`` and - can be either a string (that specifies a directory) or a - callable (that returns a filepath). Callable values should - accept the following arguments: - - - instance -- The model instance this spec belongs to - - path -- The path of the original image - - specname -- the property name that the spec is bound to on - the model instance - - extension -- A recommended extension. If the format of the - spec is set explicitly, this suggestion will be - based on that format. if not, the extension of the - original file will be passed. You do not have to use - this extension, it's only a recommendation. :param autoconvert: Specifies whether automatic conversion using ``prepare_image()`` should be performed prior to saving. :param image_cache_backend: An object responsible for managing the state @@ -71,7 +56,6 @@ def __init__(self, processors=None, format=None, options=None, autoconvert=autoconvert, storage=storage) self.image_field = image_field self.storage = storage - self.cache_to = cache_to self.image_cache_backend = image_cache_backend or \ get_default_image_cache_backend() diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index d6f3dc20..c213ac3f 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,10 +1,4 @@ -import os -import datetime - from django.db.models.fields.files import ImageField, ImageFieldFile -from django.utils.encoding import force_unicode, smart_str - -from ...utils import suggest_extension class ImageSpecFieldFile(ImageFieldFile): @@ -89,52 +83,13 @@ def delete(self, save=False): if save: self.instance.save() - def _default_cache_to(self, instance, path, specname, extension): - """ - Determines the filename to use for the transformed image. Can be - overridden on a per-spec basis by setting the cache_to property on - the spec. - - """ - filepath, basename = os.path.split(path) - filename = os.path.splitext(basename)[0] - new_name = '%s_%s%s' % (filename, specname, extension) - return os.path.join('cache', filepath, new_name) - @property def name(self): """ - Specifies the filename that the cached image will use. The user can - control this by providing a `cache_to` method to the ImageSpecField. + Specifies the filename that the cached image will use. """ - name = getattr(self, '_name', None) - if not name: - filename = self.source_file.name - new_filename = None - if filename: - cache_to = self.field.cache_to or self._default_cache_to - - if not cache_to: - raise Exception('No cache_to or default_cache_to value' - ' specified') - if callable(cache_to): - suggested_extension = suggest_extension( - self.source_file.name, self.field.generator.format) - new_filename = force_unicode( - datetime.datetime.now().strftime( - smart_str(cache_to(self.instance, - self.source_file.name, self.attname, - suggested_extension)))) - else: - dir_name = os.path.normpath( - force_unicode(datetime.datetime.now().strftime( - smart_str(cache_to)))) - filename = os.path.normpath(os.path.basename(filename)) - new_filename = os.path.join(dir_name, filename) - - self._name = new_filename - return self._name + return self.field.generator.generate_filename(self.source_file) @name.setter def name(self, value): From 197dfb3485112b25ace247d03955304957e88129 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Sep 2012 21:32:57 -0400 Subject: [PATCH 009/527] Add VALIDATE_ON_ACCESS setting --- imagekit/conf.py | 1 + imagekit/models/fields/__init__.py | 7 ++++++- imagekit/models/fields/files.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 4f3b95c1..3d8a6511 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,4 +3,5 @@ class ImageKitConf(AppConf): DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend' + VALIDATE_ON_ACCESS = True CACHE_DIR = 'CACHE/images' diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index faa5fb58..078f814a 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,5 +1,6 @@ import os +from django.conf import settings from django.db import models from django.db.models.signals import post_init, post_save, post_delete @@ -18,7 +19,7 @@ class ImageSpecField(object): """ def __init__(self, processors=None, format=None, options=None, image_field=None, pre_cache=None, storage=None, autoconvert=True, - image_cache_backend=None): + image_cache_backend=None, validate_on_access=None): """ :param processors: A list of processors to run on the original image. :param format: The format of the output file. If not provided, @@ -38,6 +39,8 @@ def __init__(self, processors=None, format=None, options=None, :param image_cache_backend: An object responsible for managing the state of cached files. Defaults to an instance of IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND + :param validate_on_access: Should the image cache be validated when it's + accessed? """ @@ -58,6 +61,8 @@ def __init__(self, processors=None, format=None, options=None, self.storage = storage self.image_cache_backend = image_cache_backend or \ get_default_image_cache_backend() + self.validate_on_access = settings.IMAGEKIT_VALIDATE_ON_ACCESS if \ + validate_on_access is None else validate_on_access def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index c213ac3f..b46d8131 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -31,7 +31,7 @@ def source_file(self): def _require_file(self): if not self.source_file: raise ValueError("The '%s' attribute's image_field has no file associated with it." % self.attname) - else: + elif self.field.validate_on_access: self.validate() def clear(self): From 0fc29ee7cf220c99225b1256b718c9dc32e4862c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Sep 2012 21:50:11 -0400 Subject: [PATCH 010/527] Extract useful backend utils --- imagekit/imagecache/__init__.py | 34 ++++++-------------------------- imagekit/utils.py | 35 ++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/imagekit/imagecache/__init__.py b/imagekit/imagecache/__init__.py index cf98a9d8..93dfe1bb 100644 --- a/imagekit/imagecache/__init__.py +++ b/imagekit/imagecache/__init__.py @@ -1,34 +1,12 @@ -from django.core.exceptions import ImproperlyConfigured -from django.utils.importlib import import_module - -from imagekit.imagecache.base import InvalidImageCacheBackendError, PessimisticImageCacheBackend, NonValidatingImageCacheBackend - -_default_image_cache_backend = None +from ..utils import get_singleton +from .base import InvalidImageCacheBackendError, PessimisticImageCacheBackend, NonValidatingImageCacheBackend def get_default_image_cache_backend(): """ - Get the default image cache backend. Uses the same method as - django.core.file.storage.get_storage_class + Get the default validation backend. """ - global _default_image_cache_backend - if not _default_image_cache_backend: - from django.conf import settings - import_path = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND - try: - dot = import_path.rindex('.') - except ValueError: - raise ImproperlyConfigured("%s isn't an image cache backend module." % \ - import_path) - module, classname = import_path[:dot], import_path[dot + 1:] - try: - mod = import_module(module) - except ImportError, e: - raise ImproperlyConfigured('Error importing image cache backend module %s: "%s"' % (module, e)) - try: - cls = getattr(mod, classname) - _default_image_cache_backend = cls() - except AttributeError: - raise ImproperlyConfigured('Image cache backend module "%s" does not define a "%s" class.' % (module, classname)) - return _default_image_cache_backend + from django.conf import settings + return get_singleton(settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND, + 'validation backend') diff --git a/imagekit/utils.py b/imagekit/utils.py index 4ffb556c..0fd1b5db 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -3,10 +3,12 @@ import sys import types +from django.core.exceptions import ImproperlyConfigured from django.core.files.base import ContentFile from django.db.models.loading import cache -from django.utils.functional import wraps from django.utils.encoding import smart_str, smart_unicode +from django.utils.functional import wraps +from django.utils.importlib import import_module from .lib import Image, ImageFile, StringIO @@ -371,3 +373,34 @@ def prepare_image(img, format): save_kwargs['optimize'] = True return img, save_kwargs + + +def get_class(path, desc): + try: + dot = path.rindex('.') + except ValueError: + raise ImproperlyConfigured("%s isn't a %s module." % (path, desc)) + module, classname = path[:dot], path[dot + 1:] + try: + mod = import_module(module) + except ImportError, e: + raise ImproperlyConfigured('Error importing %s module %s: "%s"' % + (desc, module, e)) + try: + cls = getattr(mod, classname) + return cls + except AttributeError: + raise ImproperlyConfigured('%s module "%s" does not define a "%s"' + ' class.' % (desc[0].upper() + desc[1:], module, classname)) + + +_singletons = {} + + +def get_singleton(class_path, desc): + global _singletons + cls = get_class(class_path, desc) + instance = _singletons.get(cls) + if not instance: + instance = _singletons[cls] = cls() + return instance From 3103ab29bd208545ddd2e9a70f36ec9581489b90 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Sep 2012 21:54:41 -0400 Subject: [PATCH 011/527] Remove "non-validating" backend It's been superseded by the VALIDATE_ON_ACCESS setting --- imagekit/imagecache/__init__.py | 4 ++-- imagekit/imagecache/base.py | 27 --------------------------- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/imagekit/imagecache/__init__.py b/imagekit/imagecache/__init__.py index 93dfe1bb..4680104a 100644 --- a/imagekit/imagecache/__init__.py +++ b/imagekit/imagecache/__init__.py @@ -1,5 +1,5 @@ from ..utils import get_singleton -from .base import InvalidImageCacheBackendError, PessimisticImageCacheBackend, NonValidatingImageCacheBackend +from .base import InvalidImageCacheBackendError, PessimisticImageCacheBackend def get_default_image_cache_backend(): @@ -9,4 +9,4 @@ def get_default_image_cache_backend(): """ from django.conf import settings return get_singleton(settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND, - 'validation backend') + 'image cache backend') diff --git a/imagekit/imagecache/base.py b/imagekit/imagecache/base.py index f06c9b5a..c0ec5669 100644 --- a/imagekit/imagecache/base.py +++ b/imagekit/imagecache/base.py @@ -31,30 +31,3 @@ def invalidate(self, file): def clear(self, file): file.delete(save=False) - - -class NonValidatingImageCacheBackend(object): - """ - A backend that is super optimistic about the existence of spec files. It - will hit your file storage much less frequently than the pessimistic - backend, but it is technically possible for a cache file to be missing - after validation. - - """ - - def validate(self, file): - """ - NonValidatingImageCacheBackend has faith, so validate's a no-op. - - """ - pass - - def invalidate(self, file): - """ - Immediately generate a new spec file upon invalidation. - - """ - file.generate(save=True) - - def clear(self, file): - file.delete(save=False) From 2ad3791d9d5925868142cba26868ad2a16a3f810 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Sep 2012 22:19:46 -0400 Subject: [PATCH 012/527] Reorganize image cache backends --- imagekit/conf.py | 2 +- imagekit/imagecache/__init__.py | 12 ------ imagekit/imagecache/backends/__init__.py | 2 + imagekit/imagecache/{ => backends}/base.py | 18 +++++++-- imagekit/imagecache/backends/celery.py | 35 ++++++++++++++++++ imagekit/imagecache/celery.py | 43 ---------------------- imagekit/models/fields/__init__.py | 2 +- 7 files changed, 54 insertions(+), 60 deletions(-) create mode 100644 imagekit/imagecache/backends/__init__.py rename imagekit/imagecache/{ => backends}/base.py (59%) create mode 100644 imagekit/imagecache/backends/celery.py delete mode 100644 imagekit/imagecache/celery.py diff --git a/imagekit/conf.py b/imagekit/conf.py index 3d8a6511..5618bcbb 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -2,6 +2,6 @@ class ImageKitConf(AppConf): - DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.PessimisticImageCacheBackend' + DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.backends.Simple' VALIDATE_ON_ACCESS = True CACHE_DIR = 'CACHE/images' diff --git a/imagekit/imagecache/__init__.py b/imagekit/imagecache/__init__.py index 4680104a..e69de29b 100644 --- a/imagekit/imagecache/__init__.py +++ b/imagekit/imagecache/__init__.py @@ -1,12 +0,0 @@ -from ..utils import get_singleton -from .base import InvalidImageCacheBackendError, PessimisticImageCacheBackend - - -def get_default_image_cache_backend(): - """ - Get the default validation backend. - - """ - from django.conf import settings - return get_singleton(settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND, - 'image cache backend') diff --git a/imagekit/imagecache/backends/__init__.py b/imagekit/imagecache/backends/__init__.py new file mode 100644 index 00000000..a733a93d --- /dev/null +++ b/imagekit/imagecache/backends/__init__.py @@ -0,0 +1,2 @@ +from .base import * +from .celery import * diff --git a/imagekit/imagecache/base.py b/imagekit/imagecache/backends/base.py similarity index 59% rename from imagekit/imagecache/base.py rename to imagekit/imagecache/backends/base.py index c0ec5669..91a319fd 100644 --- a/imagekit/imagecache/base.py +++ b/imagekit/imagecache/backends/base.py @@ -1,14 +1,26 @@ +from ...utils import get_singleton from django.core.exceptions import ImproperlyConfigured +def get_default_image_cache_backend(): + """ + Get the default image cache backend. + + """ + from django.conf import settings + return get_singleton(settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND, + 'image cache backend') + + class InvalidImageCacheBackendError(ImproperlyConfigured): pass -class PessimisticImageCacheBackend(object): +class Simple(object): """ - A very safe image cache backend. Guarantees that files will always be - available, but at the cost of hitting the storage backend. + The most basic image cache backend. Files are considered valid if they + exist. To invalidate a file, it's deleted; to validate one, it's generated + immediately. """ diff --git a/imagekit/imagecache/backends/celery.py b/imagekit/imagecache/backends/celery.py new file mode 100644 index 00000000..f3c103de --- /dev/null +++ b/imagekit/imagecache/backends/celery.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +from .base import InvalidImageCacheBackendError, Simple as SimpleBackend + + +def generate(model, pk, attr): + try: + instance = model._default_manager.get(pk=pk) + except model.DoesNotExist: + pass # The model was deleted since the task was scheduled. NEVER MIND! + else: + field_file = getattr(instance, attr) + field_file.delete(save=False) + field_file.generate(save=True) + + +class CeleryBackend(SimpleBackend): + """ + An image cache backend that uses celery to generate images. + + """ + def __init__(self): + try: + from celery.task import task + except: + raise InvalidImageCacheBackendError("Celery validation backend requires the 'celery' library") + if not getattr(CeleryBackend, '_task', None): + CeleryBackend._task = task(generate) + + def invalidate(self, file): + self._task.delay(file.instance.__class__, file.instance.pk, file.attname) + + def clear(self, file): + file.delete(save=False) diff --git a/imagekit/imagecache/celery.py b/imagekit/imagecache/celery.py deleted file mode 100644 index 9dee5cad..00000000 --- a/imagekit/imagecache/celery.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import - -from imagekit.imagecache import PessimisticImageCacheBackend, InvalidImageCacheBackendError - - -def generate(model, pk, attr): - try: - instance = model._default_manager.get(pk=pk) - except model.DoesNotExist: - pass # The model was deleted since the task was scheduled. NEVER MIND! - else: - field_file = getattr(instance, attr) - field_file.delete(save=False) - field_file.generate(save=True) - - -class CeleryImageCacheBackend(PessimisticImageCacheBackend): - """ - A pessimistic cache state backend that uses celery to generate its spec - images. Like PessimisticCacheStateBackend, this one checks to see if the - file exists on validation, so the storage is hit fairly frequently, but an - image is guaranteed to exist. However, while validation guarantees the - existence of *an* image, it does not necessarily guarantee that you will get - the correct image, as the spec may be pending regeneration. In other words, - while there are `generate` tasks in the queue, it is possible to get a - stale spec image. The tradeoff is that calling `invalidate()` won't block - to interact with file storage. - - """ - def __init__(self): - try: - from celery.task import task - except: - raise InvalidImageCacheBackendError("Celery image cache backend requires the 'celery' library") - if not getattr(CeleryImageCacheBackend, '_task', None): - CeleryImageCacheBackend._task = task(generate) - - def invalidate(self, file): - self._task.delay(file.instance.__class__, file.instance.pk, file.attname) - - def clear(self, file): - file.delete(save=False) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 078f814a..49278dc3 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -4,7 +4,7 @@ from django.db import models from django.db.models.signals import post_init, post_save, post_delete -from ...imagecache import get_default_image_cache_backend +from ...imagecache.backends import get_default_image_cache_backend from ...generators import SpecFileGenerator from .files import ImageSpecFieldFile, ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor, ImageKitMeta, BoundImageKitMeta From 8a2738ca8ad28ed11cae842f1dec48da86a0a985 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 6 Sep 2012 00:07:40 -0400 Subject: [PATCH 013/527] Add backend for caching image state --- imagekit/conf.py | 2 ++ imagekit/generators.py | 16 +++++---- imagekit/imagecache/backends/base.py | 49 +++++++++++++++++++++++++--- imagekit/models/fields/files.py | 3 ++ 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 5618bcbb..6c092329 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,5 +3,7 @@ class ImageKitConf(AppConf): DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.backends.Simple' + CACHE_BACKEND = None VALIDATE_ON_ACCESS = True CACHE_DIR = 'CACHE/images' + CACHE_PREFIX = 'ik-' diff --git a/imagekit/generators.py b/imagekit/generators.py index 344fc672..6c4a974d 100644 --- a/imagekit/generators.py +++ b/imagekit/generators.py @@ -49,18 +49,20 @@ def process_content(self, content, filename=None, source_file=None): content = IKContentFile(filename, imgfile.read(), format=format) return img, content + def get_hash(self, source_file): + return md5(''.join([ + pickle.dumps(self.get_processors(source_file)), + self.format, + pickle.dumps(self.options), + str(self.autoconvert), + ])).hexdigest() + def generate_filename(self, source_file): source_filename = source_file.name filename = None if source_filename: - hash = md5(''.join([ - pickle.dumps(self.get_processors(source_file)), - self.format, - pickle.dumps(self.options), - str(self.autoconvert), - ])).hexdigest() + hash = self.get_hash(source_file) extension = suggest_extension(source_filename, self.format) - filename = os.path.normpath(os.path.join( settings.IMAGEKIT_CACHE_DIR, os.path.splitext(source_filename)[0], diff --git a/imagekit/imagecache/backends/base.py b/imagekit/imagecache/backends/base.py index 91a319fd..a489f6d6 100644 --- a/imagekit/imagecache/backends/base.py +++ b/imagekit/imagecache/backends/base.py @@ -1,4 +1,6 @@ from ...utils import get_singleton +from django.core.cache import get_cache +from django.core.cache.backends.dummy import DummyCache from django.core.exceptions import ImproperlyConfigured @@ -16,7 +18,39 @@ class InvalidImageCacheBackendError(ImproperlyConfigured): pass -class Simple(object): +class CachedValidationBackend(object): + @property + def cache(self): + if not getattr(self, '_cache', None): + from django.conf import settings + alias = settings.IMAGEKIT_CACHE_BACKEND + self._cache = get_cache(alias) if alias else DummyCache(None, {}) + return self._cache + + def get_key(self, file): + from django.conf import settings + return '%s%s-valid' % (settings.IMAGEKIT_CACHE_PREFIX, file.get_hash()) + + def is_invalid(self, file): + key = self.get_key(file) + cached_value = self.cache.get(key) + if cached_value is None: + cached_value = self._is_invalid(file) + self.cache.set(key, cached_value) + return cached_value + + def validate(self, file): + if self.is_invalid(file): + self._validate(file) + self.cache.set(self.get_key(file), True) + + def invalidate(self, file): + if not self.is_invalid(file): + self._invalidate(file) + self.cache.set(self.get_key(file), False) + + +class Simple(CachedValidationBackend): """ The most basic image cache backend. Files are considered valid if they exist. To invalidate a file, it's deleted; to validate one, it's generated @@ -24,21 +58,26 @@ class Simple(object): """ - def is_invalid(self, file): + def _is_invalid(self, file): if not getattr(file, '_file', None): # No file on object. Have to check storage. return not file.storage.exists(file.name) return False - def validate(self, file): + def _validate(self, file): """ Generates a new image by running the processors on the source file. """ - if self.is_invalid(file): - file.generate(save=True) + file.generate(save=True) def invalidate(self, file): + """ + Invalidate the file by deleting it. We override ``invalidate()`` + instead of ``_invalidate()`` because we don't really care to check + whether the file is invalid or not. + + """ file.delete(save=False) def clear(self, file): diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index b46d8131..687295f0 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -6,6 +6,9 @@ def __init__(self, instance, field, attname): super(ImageSpecFieldFile, self).__init__(instance, field, None) self.attname = attname + def get_hash(self): + return self.field.generator.get_hash(self.source_file) + @property def source_file(self): field_name = getattr(self.field, 'image_field', None) From ec9a1f1fda56bfea568e25ddc5eabda7e9d32a1a Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Thu, 6 Sep 2012 15:29:57 -0400 Subject: [PATCH 014/527] Spec templatetag returns html by default ...if no 'as var' is provided or if the var is printed directly. --- imagekit/files.py | 4 +- imagekit/templatetags/imagekit_tags.py | 70 +++++++++++++++++--------- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index ddfa4a8f..c2ec36c8 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -3,7 +3,7 @@ from django.db.models.fields.files import ImageFieldFile from .generators import SpecFileGenerator -from .utils import SpecWrapper +from .utils import SpecWrapper, suggest_extension class ImageSpecFile(ImageFieldFile): @@ -44,7 +44,7 @@ def name(self): source_filename = self.source_file.name filepath, basename = os.path.split(source_filename) filename = os.path.splitext(basename)[0] - extension = self.generator.suggest_extension(source_filename) + extension = suggest_extension(source_filename, self.generator.format) new_name = '%s%s' % (filename, extension) cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ [filepath, new_name] diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 0cb21ed1..90a55844 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,5 +1,6 @@ import os from django import template +from django.utils.safestring import mark_safe from ..files import ImageSpecFile @@ -40,42 +41,55 @@ def get_spec(self, id): spec_registry = SpecRegistry() +class ImageSpecFileHtmlWrapper(object): + def __init__(self, image_spec_file): + self._image_spec_file = image_spec_file + + def __getattr__(self, name): + return getattr(self._image_spec_file, name) + + def __unicode__(self): + return mark_safe(u'' % self.url) + + class SpecNode(template.Node): - def __init__(self, spec_id, source_image, variable_name): + def __init__(self, spec_id, source_image, variable_name=None): self.spec_id = spec_id self.source_image = source_image self.variable_name = variable_name - def _default_cache_to(self, instance, path, specname, extension): - """ - Determines the filename to use for the transformed image. Can be - overridden on a per-spec basis by setting the cache_to property on - the spec. - - """ - filepath, basename = os.path.split(path) - filename = os.path.splitext(basename)[0] - new_name = '%s_%s%s' % (filename, specname, extension) - return os.path.join(os.path.join('cache', filepath), new_name) - def render(self, context): from ..utils import autodiscover autodiscover() source_image = self.source_image.resolve(context) - variable_name = str(self.variable_name) spec_id = self.spec_id.resolve(context) spec = spec_registry.get_spec(spec_id) if callable(spec): spec = spec() - context[variable_name] = ImageSpecFile(spec, source_image, spec_id) - return '' + spec_file = ImageSpecFileHtmlWrapper(ImageSpecFile(spec, source_image, spec_id)) + if self.variable_name is not None: + variable_name = str(self.variable_name) + context[variable_name] = spec_file + return '' + + return spec_file #@register.tag +# TODO: Should this be renamed to something like 'process'? def spec(parser, token): """ - Creates an image based on the provided spec and source image and sets it - as a context variable: + Creates an image based on the provided spec and source image. + + By default:: + + {% spec 'myapp:thumbnail', mymodel.profile_image %} + + Generates an ````:: + + + + Storing it as a context variable allows more flexibility:: {% spec 'myapp:thumbnail' mymodel.profile_image as th %} @@ -83,12 +97,20 @@ def spec(parser, token): """ args = token.split_contents() - - if len(args) != 5 or args[3] != 'as': - raise TemplateSyntaxError('\'spec\' tags must be in the form "{% spec spec_id image as varname %}"') - - return SpecNode(*[parser.compile_filter(arg) for arg in args[1:3] \ - + [args[4]]]) + arg_count = len(args) + + if (arg_count < 3 or arg_count > 5 + or (arg_count > 3 and arg_count < 5) + or (args == 5 and args[3] != 'as')): + raise template.TemplateSyntaxError('\'spec\' tags must be in the form' + ' "{% spec spec_id image %}" or' + ' "{% spec spec_id image' + ' as varname %}"') + + spec_id = parser.compile_filter(args[1]) + source_image = parser.compile_filter(args[2]) + variable_name = arg_count > 3 and args[4] or None + return SpecNode(spec_id, source_image, variable_name) spec = spec_tag = register.tag(spec) From f43bd4ec28468c8e85859a1a4d00cf9d77c3486f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 15 Sep 2012 15:09:58 -0400 Subject: [PATCH 015/527] Include source filename in hash --- imagekit/generators.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/generators.py b/imagekit/generators.py index 6c4a974d..515bcb72 100644 --- a/imagekit/generators.py +++ b/imagekit/generators.py @@ -51,6 +51,7 @@ def process_content(self, content, filename=None, source_file=None): def get_hash(self, source_file): return md5(''.join([ + source_file.name, pickle.dumps(self.get_processors(source_file)), self.format, pickle.dumps(self.options), From ba9bf1f8771a4d5c89ce53b280a537ea67303059 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 3 Oct 2012 22:23:11 -0400 Subject: [PATCH 016/527] Add image cache strategies This new feature gives the user more control over *when* their images are validated. Image cache backends are now exclusively for controlling the *how*. This means you won't have to write a lot of code when you just want to change one or the other. --- imagekit/conf.py | 3 +- imagekit/generators.py | 2 +- imagekit/imagecache/actions.py | 23 ++++++++ .../{backends/base.py => backends.py} | 2 +- imagekit/imagecache/backends/__init__.py | 2 - imagekit/imagecache/backends/celery.py | 35 ------------ imagekit/imagecache/strategies.py | 57 +++++++++++++++++++ imagekit/models/fields/__init__.py | 24 +++++--- imagekit/models/fields/files.py | 3 +- 9 files changed, 100 insertions(+), 51 deletions(-) create mode 100644 imagekit/imagecache/actions.py rename imagekit/imagecache/{backends/base.py => backends.py} (98%) delete mode 100644 imagekit/imagecache/backends/__init__.py delete mode 100644 imagekit/imagecache/backends/celery.py create mode 100644 imagekit/imagecache/strategies.py diff --git a/imagekit/conf.py b/imagekit/conf.py index 6c092329..e43d04eb 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -1,9 +1,10 @@ from appconf import AppConf +from .imagecache.actions import validate_now, clear_now class ImageKitConf(AppConf): DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.backends.Simple' CACHE_BACKEND = None - VALIDATE_ON_ACCESS = True CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'ik-' + DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' diff --git a/imagekit/generators.py b/imagekit/generators.py index 515bcb72..e8489815 100644 --- a/imagekit/generators.py +++ b/imagekit/generators.py @@ -56,7 +56,7 @@ def get_hash(self, source_file): self.format, pickle.dumps(self.options), str(self.autoconvert), - ])).hexdigest() + ]).encode('utf-8')).hexdigest() def generate_filename(self, source_file): source_filename = source_file.name diff --git a/imagekit/imagecache/actions.py b/imagekit/imagecache/actions.py new file mode 100644 index 00000000..11c0534a --- /dev/null +++ b/imagekit/imagecache/actions.py @@ -0,0 +1,23 @@ +def validate_now(file): + print 'validate now!' + file.validate() + + +try: + from celery.task import task +except ImportError: + pass +else: + validate_now_task = task(validate_now) + + +def deferred_validate(file): + try: + import celery + except: + raise ImportError("Deferred validation requires the the 'celery' library") + validate_now_task.delay(file) + + +def clear_now(file): + file.clear() diff --git a/imagekit/imagecache/backends/base.py b/imagekit/imagecache/backends.py similarity index 98% rename from imagekit/imagecache/backends/base.py rename to imagekit/imagecache/backends.py index a489f6d6..cbb7f5d5 100644 --- a/imagekit/imagecache/backends/base.py +++ b/imagekit/imagecache/backends.py @@ -1,4 +1,4 @@ -from ...utils import get_singleton +from ..utils import get_singleton from django.core.cache import get_cache from django.core.cache.backends.dummy import DummyCache from django.core.exceptions import ImproperlyConfigured diff --git a/imagekit/imagecache/backends/__init__.py b/imagekit/imagecache/backends/__init__.py deleted file mode 100644 index a733a93d..00000000 --- a/imagekit/imagecache/backends/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .base import * -from .celery import * diff --git a/imagekit/imagecache/backends/celery.py b/imagekit/imagecache/backends/celery.py deleted file mode 100644 index f3c103de..00000000 --- a/imagekit/imagecache/backends/celery.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import - -from .base import InvalidImageCacheBackendError, Simple as SimpleBackend - - -def generate(model, pk, attr): - try: - instance = model._default_manager.get(pk=pk) - except model.DoesNotExist: - pass # The model was deleted since the task was scheduled. NEVER MIND! - else: - field_file = getattr(instance, attr) - field_file.delete(save=False) - field_file.generate(save=True) - - -class CeleryBackend(SimpleBackend): - """ - An image cache backend that uses celery to generate images. - - """ - def __init__(self): - try: - from celery.task import task - except: - raise InvalidImageCacheBackendError("Celery validation backend requires the 'celery' library") - if not getattr(CeleryBackend, '_task', None): - CeleryBackend._task = task(generate) - - def invalidate(self, file): - self._task.delay(file.instance.__class__, file.instance.pk, file.attname) - - def clear(self, file): - file.delete(save=False) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py new file mode 100644 index 00000000..7ec72528 --- /dev/null +++ b/imagekit/imagecache/strategies.py @@ -0,0 +1,57 @@ +from .actions import validate_now, clear_now +from ..utils import get_singleton + + +class Pessimistic(object): + """ + A caching strategy that validates the file every time it's accessed. + + """ + + def on_access(self, file): + validate_now(file) + + def on_source_delete(self, file): + clear_now(file) + + def on_source_change(self, file): + validate_now(file) + + +class Optimistic(object): + """ + A caching strategy that validates when the source file changes and assumes + that the cached file will persist. + + """ + + def on_source_create(self, file): + validate_now(file) + + def on_source_delete(self, file): + clear_now(file) + + def on_source_change(self, file): + validate_now(file) + + +class DictStrategy(object): + def __init__(self, callbacks): + for k, v in callbacks.items(): + setattr(self, k, v) + + +class StrategyWrapper(object): + def __init__(self, strategy): + if isinstance(strategy, basestring): + strategy = get_singleton(strategy, 'image cache strategy') + elif isinstance(strategy, dict): + strategy = DictStrategy(strategy) + elif callable(strategy): + strategy = strategy() + self._wrapped = strategy + + def invoke_callback(self, name, *args, **kwargs): + func = getattr(self._wrapped, 'on_%s' % name, None) + if func: + func(*args, **kwargs) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 49278dc3..fdb4475e 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -5,6 +5,7 @@ from django.db.models.signals import post_init, post_save, post_delete from ...imagecache.backends import get_default_image_cache_backend +from ...imagecache.strategies import StrategyWrapper from ...generators import SpecFileGenerator from .files import ImageSpecFieldFile, ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor, ImageKitMeta, BoundImageKitMeta @@ -19,7 +20,7 @@ class ImageSpecField(object): """ def __init__(self, processors=None, format=None, options=None, image_field=None, pre_cache=None, storage=None, autoconvert=True, - image_cache_backend=None, validate_on_access=None): + image_cache_backend=None, image_cache_strategy=None): """ :param processors: A list of processors to run on the original image. :param format: The format of the output file. If not provided, @@ -38,9 +39,10 @@ def __init__(self, processors=None, format=None, options=None, ``prepare_image()`` should be performed prior to saving. :param image_cache_backend: An object responsible for managing the state of cached files. Defaults to an instance of - IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND - :param validate_on_access: Should the image cache be validated when it's - accessed? + ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` + :param image_cache_strategy: A dictionary containing callbacks that + allow you to customize how and when the image cache is validated. + Defaults to ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY`` """ @@ -61,8 +63,9 @@ def __init__(self, processors=None, format=None, options=None, self.storage = storage self.image_cache_backend = image_cache_backend or \ get_default_image_cache_backend() - self.validate_on_access = settings.IMAGEKIT_VALIDATE_ON_ACCESS if \ - validate_on_access is None else validate_on_access + if image_cache_strategy is None: + image_cache_strategy = settings.IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY + self.image_cache_strategy = StrategyWrapper(image_cache_strategy) def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) @@ -101,8 +104,11 @@ def _post_save_receiver(sender, instance=None, created=False, raw=False, **kwarg old_hashes = instance._ik._source_hashes.copy() new_hashes = ImageSpecField._update_source_hashes(instance) for attname in instance._ik.spec_fields: - if old_hashes[attname] != new_hashes[attname]: - getattr(instance, attname).invalidate() + file = getattr(instance, attname) + if created: + file.field.image_cache_strategy.invoke_callback('source_create', file) + elif old_hashes[attname] != new_hashes[attname]: + file.field.image_cache_strategy.invoke_callback('source_change', file) @staticmethod def _update_source_hashes(instance): @@ -119,7 +125,7 @@ def _update_source_hashes(instance): @staticmethod def _post_delete_receiver(sender, instance=None, **kwargs): for spec_file in instance._ik.spec_files: - spec_file.clear() + spec_file.field.image_cache_strategy.invoke_callback('source_delete', spec_file) @staticmethod def _post_init_receiver(sender, instance, **kwargs): diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 687295f0..2d588456 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -34,8 +34,7 @@ def source_file(self): def _require_file(self): if not self.source_file: raise ValueError("The '%s' attribute's image_field has no file associated with it." % self.attname) - elif self.field.validate_on_access: - self.validate() + self.field.image_cache_strategy.invoke_callback('access', self) def clear(self): return self.field.image_cache_backend.clear(self) From c8778b9cfb07eb1b955ff34a9fd185ffd155386b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 3 Oct 2012 22:31:45 -0400 Subject: [PATCH 017/527] Remove print statement --- imagekit/imagecache/actions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imagekit/imagecache/actions.py b/imagekit/imagecache/actions.py index 11c0534a..2e222b3e 100644 --- a/imagekit/imagecache/actions.py +++ b/imagekit/imagecache/actions.py @@ -1,5 +1,4 @@ def validate_now(file): - print 'validate now!' file.validate() From d2087aa1685afe5947b40c186e4673dd401d7a74 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 21:37:20 -0400 Subject: [PATCH 018/527] Create ImageSpecs; remove generators --- imagekit/__init__.py | 4 ++ imagekit/{generators.py => base.py} | 103 ++++++++++++++++++++-------- imagekit/conf.py | 2 +- imagekit/exceptions.py | 8 +++ imagekit/files.py | 8 +-- imagekit/models/__init__.py | 9 --- imagekit/models/fields/__init__.py | 81 +++++++--------------- imagekit/models/fields/files.py | 18 ++--- imagekit/utils.py | 9 +-- tests/core/tests.py | 3 +- 10 files changed, 127 insertions(+), 118 deletions(-) rename imagekit/{generators.py => base.py} (51%) create mode 100644 imagekit/exceptions.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 55a5d048..ee903d93 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,3 +1,7 @@ +from . import conf +from .base import ImageSpec + + __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' __version__ = (2, 0, 1, 'final', 0) diff --git a/imagekit/generators.py b/imagekit/base.py similarity index 51% rename from imagekit/generators.py rename to imagekit/base.py index e8489815..30b34cc4 100644 --- a/imagekit/generators.py +++ b/imagekit/base.py @@ -2,20 +2,26 @@ from hashlib import md5 import os import pickle +from .exceptions import UnknownExtensionError +from .imagecache.backends import get_default_image_cache_backend +from .imagecache.strategies import StrategyWrapper from .lib import StringIO from .processors import ProcessorPipeline -from .utils import (img_to_fobj, open_image, IKContentFile, extension_to_format, - suggest_extension, UnknownExtensionError) +from .utils import (open_image, extension_to_format, IKContentFile, img_to_fobj, + suggest_extension) -class SpecFileGenerator(object): - def __init__(self, processors=None, format=None, options=None, - autoconvert=True, storage=None): - self.processors = processors - self.format = format - self.options = options or {} - self.autoconvert = autoconvert - self.storage = storage +class BaseImageSpec(object): + processors = None + format = None + options = None + autoconvert = True + + def __init__(self, processors=None, format=None, options=None, autoconvert=None): + self.processors = processors or self.processors or [] + self.format = format or self.format + self.options = options or self.options + self.autoconvert = self.autoconvert if autoconvert is None else autoconvert def get_processors(self, source_file): processors = self.processors @@ -23,6 +29,28 @@ def get_processors(self, source_file): processors = processors(source_file) return processors + def get_hash(self, source_file): + return md5(''.join([ + source_file.name, + pickle.dumps(self.get_processors(source_file)), + self.format, + pickle.dumps(self.options), + str(self.autoconvert), + ]).encode('utf-8')).hexdigest() + + def generate_filename(self, source_file): + source_filename = source_file.name + filename = None + if source_filename: + hash = self.get_hash(source_file) + extension = suggest_extension(source_filename, self.format) + filename = os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (hash, extension))) + + return filename + def process_content(self, content, filename=None, source_file=None): img = open_image(content) original_format = img.format @@ -49,27 +77,44 @@ def process_content(self, content, filename=None, source_file=None): content = IKContentFile(filename, imgfile.read(), format=format) return img, content - def get_hash(self, source_file): - return md5(''.join([ - source_file.name, - pickle.dumps(self.get_processors(source_file)), - self.format, - pickle.dumps(self.options), - str(self.autoconvert), - ]).encode('utf-8')).hexdigest() - def generate_filename(self, source_file): - source_filename = source_file.name - filename = None - if source_filename: - hash = self.get_hash(source_file) - extension = suggest_extension(source_filename, self.format) - filename = os.path.normpath(os.path.join( - settings.IMAGEKIT_CACHE_DIR, - os.path.splitext(source_filename)[0], - '%s%s' % (hash, extension))) +class ImageSpec(BaseImageSpec): + storage = None + image_cache_backend = None + image_cache_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY - return filename + def __init__(self, processors=None, format=None, options=None, + storage=None, autoconvert=None, image_cache_backend=None, + image_cache_strategy=None): + """ + :param processors: A list of processors to run on the original image. + :param format: The format of the output file. If not provided, + ImageSpecField will try to guess the appropriate format based on the + extension of the filename and the format of the input image. + :param options: A dictionary that will be passed to PIL's + ``Image.save()`` method as keyword arguments. Valid options vary + between formats, but some examples include ``quality``, + ``optimize``, and ``progressive`` for JPEGs. See the PIL + documentation for others. + :param autoconvert: Specifies whether automatic conversion using + ``prepare_image()`` should be performed prior to saving. + :param image_field: The name of the model property that contains the + original image. + :param storage: A Django storage system to use to save the generated + image. + :param image_cache_backend: An object responsible for managing the state + of cached files. Defaults to an instance of + ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` + :param image_cache_strategy: A dictionary containing callbacks that + allow you to customize how and when the image cache is validated. + Defaults to ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY`` + + """ + super(ImageSpec, self).__init__(processors=processors, format=format, + options=options, autoconvert=autoconvert) + self.storage = storage or self.storage + self.image_cache_backend = image_cache_backend or self.image_cache_backend or get_default_image_cache_backend() + self.image_cache_strategy = StrategyWrapper(image_cache_strategy or self.image_cache_strategy) def generate_file(self, filename, source_file, save=True): """ diff --git a/imagekit/conf.py b/imagekit/conf.py index e43d04eb..2767e6b0 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -7,4 +7,4 @@ class ImageKitConf(AppConf): CACHE_BACKEND = None CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'ik-' - DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' + DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py new file mode 100644 index 00000000..d3595b4d --- /dev/null +++ b/imagekit/exceptions.py @@ -0,0 +1,8 @@ + + +class UnknownExtensionError(Exception): + pass + + +class UnknownFormatError(Exception): + pass diff --git a/imagekit/files.py b/imagekit/files.py index c2ec36c8..0d9837fe 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,7 +2,6 @@ from django.db.models.fields.files import ImageFieldFile -from .generators import SpecFileGenerator from .utils import SpecWrapper, suggest_extension @@ -11,9 +10,6 @@ def __init__(self, spec, source_file, spec_id): spec = SpecWrapper(spec) self.storage = spec.storage or source_file.storage - self.generator = SpecFileGenerator(processors=spec.processors, - format=spec.format, options=spec.options, - autoconvert=spec.autoconvert, storage=self.storage) self.spec = spec self.source_file = source_file @@ -44,11 +40,11 @@ def name(self): source_filename = self.source_file.name filepath, basename = os.path.split(source_filename) filename = os.path.splitext(basename)[0] - extension = suggest_extension(source_filename, self.generator.format) + extension = suggest_extension(source_filename, self.spec.format) new_name = '%s%s' % (filename, extension) cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ [filepath, new_name] return os.path.join(*cache_filename) def generate(self, save=True): - return self.generator.generate_file(self.name, self.source_file, save) + return self.spec.generate_file(self.name, self.source_file, save) diff --git a/imagekit/models/__init__.py b/imagekit/models/__init__.py index 42079877..4c3dad75 100644 --- a/imagekit/models/__init__.py +++ b/imagekit/models/__init__.py @@ -1,11 +1,2 @@ from .. import conf from .fields import ImageSpecField, ProcessedImageField -import warnings - - -class ImageSpec(ImageSpecField): - def __init__(self, *args, **kwargs): - warnings.warn('ImageSpec has been moved to' - ' imagekit.models.ImageSpecField. Please use that instead.', - DeprecationWarning) - super(ImageSpec, self).__init__(*args, **kwargs) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index fdb4475e..96852187 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,14 +1,11 @@ import os -from django.conf import settings from django.db import models from django.db.models.signals import post_init, post_save, post_delete -from ...imagecache.backends import get_default_image_cache_backend -from ...imagecache.strategies import StrategyWrapper -from ...generators import SpecFileGenerator -from .files import ImageSpecFieldFile, ProcessedImageFieldFile -from .utils import ImageSpecFileDescriptor, ImageKitMeta, BoundImageKitMeta +from .files import ProcessedImageFieldFile +from .utils import ImageSpecFileDescriptor, ImageKitMeta +from ...base import ImageSpec from ...utils import suggest_extension @@ -19,53 +16,31 @@ class ImageSpecField(object): """ def __init__(self, processors=None, format=None, options=None, - image_field=None, pre_cache=None, storage=None, autoconvert=True, + image_field=None, storage=None, autoconvert=True, image_cache_backend=None, image_cache_strategy=None): - """ - :param processors: A list of processors to run on the original image. - :param format: The format of the output file. If not provided, - ImageSpecField will try to guess the appropriate format based on the - extension of the filename and the format of the input image. - :param options: A dictionary that will be passed to PIL's - ``Image.save()`` method as keyword arguments. Valid options vary - between formats, but some examples include ``quality``, - ``optimize``, and ``progressive`` for JPEGs. See the PIL - documentation for others. - :param image_field: The name of the model property that contains the - original image. - :param storage: A Django storage system to use to save the generated - image. - :param autoconvert: Specifies whether automatic conversion using - ``prepare_image()`` should be performed prior to saving. - :param image_cache_backend: An object responsible for managing the state - of cached files. Defaults to an instance of - ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` - :param image_cache_strategy: A dictionary containing callbacks that - allow you to customize how and when the image cache is validated. - Defaults to ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY`` - - """ - if pre_cache is not None: - raise Exception('The pre_cache argument has been removed in favor' - ' of cache state backends.') - - # The generator accepts a callable value for processors, but it + # The spec accepts a callable value for processors, but it # takes different arguments than the callable that ImageSpecField # expects, so we create a partial application and pass that instead. # TODO: Should we change the signatures to match? Even if `instance` is not part of the signature, it's accessible through the source file object's instance property. p = lambda file: processors(instance=file.instance, file=file) if \ callable(processors) else processors - self.generator = SpecFileGenerator(p, format=format, options=options, - autoconvert=autoconvert, storage=storage) + self.spec = ImageSpec( + processors=p, + format=format, + options=options, + storage=storage, + autoconvert=autoconvert, + image_cache_backend=image_cache_backend, + image_cache_strategy=image_cache_strategy, + ) + self.image_field = image_field - self.storage = storage - self.image_cache_backend = image_cache_backend or \ - get_default_image_cache_backend() - if image_cache_strategy is None: - image_cache_strategy = settings.IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY - self.image_cache_strategy = StrategyWrapper(image_cache_strategy) + + @property + def storage(self): + return self.spec.storage def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) @@ -94,7 +69,7 @@ def contribute_to_class(self, cls, name): # Register the field with the image_cache_backend try: - self.image_cache_backend.register_field(cls, self, name) + self.spec.image_cache_backend.register_field(cls, self, name) except AttributeError: pass @@ -106,9 +81,9 @@ def _post_save_receiver(sender, instance=None, created=False, raw=False, **kwarg for attname in instance._ik.spec_fields: file = getattr(instance, attname) if created: - file.field.image_cache_strategy.invoke_callback('source_create', file) + file.field.spec.image_cache_strategy.invoke_callback('source_create', file) elif old_hashes[attname] != new_hashes[attname]: - file.field.image_cache_strategy.invoke_callback('source_change', file) + file.field.spec.image_cache_strategy.invoke_callback('source_change', file) @staticmethod def _update_source_hashes(instance): @@ -125,7 +100,7 @@ def _update_source_hashes(instance): @staticmethod def _post_delete_receiver(sender, instance=None, **kwargs): for spec_file in instance._ik.spec_files: - spec_file.field.image_cache_strategy.invoke_callback('source_delete', spec_file) + spec_file.field.spec.image_cache_strategy.invoke_callback('source_delete', spec_file) @staticmethod def _post_init_receiver(sender, instance, **kwargs): @@ -152,20 +127,16 @@ def __init__(self, processors=None, format=None, options=None, :class:`imagekit.models.ImageSpecField`. """ - if 'quality' in kwargs: - raise Exception('The "quality" keyword argument has been' - """ deprecated. Use `options={'quality': %s}` instead.""" \ - % kwargs['quality']) models.ImageField.__init__(self, verbose_name, name, width_field, height_field, **kwargs) - self.generator = SpecFileGenerator(processors, format=format, - options=options, autoconvert=autoconvert) + self.spec = ImageSpec(processors, format=format, options=options, + autoconvert=autoconvert) def get_filename(self, filename): filename = os.path.normpath(self.storage.get_valid_name( os.path.basename(filename))) name, ext = os.path.splitext(filename) - ext = suggest_extension(filename, self.generator.format) + ext = suggest_extension(filename, self.spec.format) return u'%s%s' % (name, ext) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 2d588456..691ce6b1 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -7,7 +7,7 @@ def __init__(self, instance, field, attname): self.attname = attname def get_hash(self): - return self.field.generator.get_hash(self.source_file) + return self.field.spec.get_hash(self.source_file) @property def source_file(self): @@ -34,16 +34,16 @@ def source_file(self): def _require_file(self): if not self.source_file: raise ValueError("The '%s' attribute's image_field has no file associated with it." % self.attname) - self.field.image_cache_strategy.invoke_callback('access', self) + self.field.spec.image_cache_strategy.invoke_callback('access', self) def clear(self): - return self.field.image_cache_backend.clear(self) + return self.field.spec.image_cache_backend.clear(self) def invalidate(self): - return self.field.image_cache_backend.invalidate(self) + return self.field.spec.image_cache_backend.invalidate(self) def validate(self): - return self.field.image_cache_backend.validate(self) + return self.field.spec.image_cache_backend.validate(self) def generate(self, save=True): """ @@ -51,7 +51,7 @@ def generate(self, save=True): the content of the result, ready for saving. """ - return self.field.generator.generate_file(self.name, self.source_file, + return self.field.spec.generate_file(self.name, self.source_file, save) def delete(self, save=False): @@ -91,7 +91,7 @@ def name(self): Specifies the filename that the cached image will use. """ - return self.field.generator.generate_filename(self.source_file) + return self.field.spec.generate_filename(self.source_file) @name.setter def name(self, value): @@ -123,7 +123,7 @@ def __setstate__(self, state): class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): - new_filename = self.field.generate_filename(self.instance, name) - img, content = self.field.generator.process_content(content, + new_filename = self.field.spec.generate_filename(self.instance, name) + img, content = self.field.spec.process_content(content, new_filename, self) return super(ProcessedImageFieldFile, self).save(name, content, save) diff --git a/imagekit/utils.py b/imagekit/utils.py index ef549f3a..fb600354 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -10,6 +10,7 @@ from django.utils.functional import wraps from django.utils.importlib import import_module +from .exceptions import UnknownExtensionError, UnknownFormatError from .lib import Image, ImageFile, StringIO @@ -76,14 +77,6 @@ def copy(self): return copy -class UnknownExtensionError(Exception): - pass - - -class UnknownFormatError(Exception): - pass - - _pil_init = 0 diff --git a/tests/core/tests.py b/tests/core/tests.py index b4884c83..4998ce55 100644 --- a/tests/core/tests.py +++ b/tests/core/tests.py @@ -5,6 +5,7 @@ from django.test import TestCase from imagekit import utils +from imagekit.exceptions import UnknownFormatError from .models import (Photo, AbstractImageModel, ConcreteImageModel1, ConcreteImageModel2) from .testutils import create_photo, pickleback @@ -59,7 +60,7 @@ def test_format_to_extension_no_init(self): self.assertEqual(utils.format_to_extension('PNG'), '.png') self.assertEqual(utils.format_to_extension('ICO'), '.ico') - with self.assertRaises(utils.UnknownFormatError): + with self.assertRaises(UnknownFormatError): utils.format_to_extension('TXT') From 0cc79384000dcb115ed3841800f0aa00bf51925c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 21:44:55 -0400 Subject: [PATCH 019/527] Re-integrate receivers module Somewhere along the line, a change got merged that stopped using the receivers module. This re-integrates it and moves changes made to the old receivers (static methods on ImageSpecField) to them. --- imagekit/models/fields/__init__.py | 46 +++--------------------------- imagekit/models/receivers.py | 9 ++++-- 2 files changed, 10 insertions(+), 45 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 96852187..34af0c73 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -5,6 +5,7 @@ from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor, ImageKitMeta +from ..receivers import configure_receivers from ...base import ImageSpec from ...utils import suggest_extension @@ -58,54 +59,12 @@ def contribute_to_class(self, cls, name): setattr(cls, '_ik', ik) ik.spec_fields.append(name) - # Connect to the signals only once for this class. - uid = '%s.%s' % (cls.__module__, cls.__name__) - post_init.connect(ImageSpecField._post_init_receiver, sender=cls, - dispatch_uid=uid) - post_save.connect(ImageSpecField._post_save_receiver, sender=cls, - dispatch_uid=uid) - post_delete.connect(ImageSpecField._post_delete_receiver, sender=cls, - dispatch_uid=uid) - # Register the field with the image_cache_backend try: self.spec.image_cache_backend.register_field(cls, self, name) except AttributeError: pass - @staticmethod - def _post_save_receiver(sender, instance=None, created=False, raw=False, **kwargs): - if not raw: - old_hashes = instance._ik._source_hashes.copy() - new_hashes = ImageSpecField._update_source_hashes(instance) - for attname in instance._ik.spec_fields: - file = getattr(instance, attname) - if created: - file.field.spec.image_cache_strategy.invoke_callback('source_create', file) - elif old_hashes[attname] != new_hashes[attname]: - file.field.spec.image_cache_strategy.invoke_callback('source_change', file) - - @staticmethod - def _update_source_hashes(instance): - """ - Stores hashes of the source image files so that they can be compared - later to see whether the source image has changed (and therefore whether - the spec file needs to be regenerated). - - """ - instance._ik._source_hashes = dict((f.attname, hash(f.source_file)) \ - for f in instance._ik.spec_files) - return instance._ik._source_hashes - - @staticmethod - def _post_delete_receiver(sender, instance=None, **kwargs): - for spec_file in instance._ik.spec_files: - spec_file.field.spec.image_cache_strategy.invoke_callback('source_delete', spec_file) - - @staticmethod - def _post_init_receiver(sender, instance, **kwargs): - ImageSpecField._update_source_hashes(instance) - class ProcessedImageField(models.ImageField): """ @@ -146,3 +105,6 @@ def get_filename(self, filename): pass else: add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$']) + + +configure_receivers() diff --git a/imagekit/models/receivers.py b/imagekit/models/receivers.py index da93a69f..67960f7e 100644 --- a/imagekit/models/receivers.py +++ b/imagekit/models/receivers.py @@ -20,14 +20,17 @@ def post_save_receiver(sender, instance=None, created=False, raw=False, **kwargs old_hashes = instance._ik._source_hashes.copy() new_hashes = update_source_hashes(instance) for attname in instance._ik.spec_fields: - if old_hashes[attname] != new_hashes[attname]: - getattr(instance, attname).invalidate() + file = getattr(instance, attname) + if created: + file.field.spec.image_cache_strategy.invoke_callback('source_create', file) + elif old_hashes[attname] != new_hashes[attname]: + file.field.spec.image_cache_strategy.invoke_callback('source_change', file) @ik_model_receiver def post_delete_receiver(sender, instance=None, **kwargs): for spec_file in instance._ik.spec_files: - spec_file.clear() + spec_file.field.spec.image_cache_strategy.invoke_callback('source_delete', spec_file) @ik_model_receiver From 30ba1d890e4f810e06057d8f53383126aa1c13fe Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 21:57:33 -0400 Subject: [PATCH 020/527] Move exceptions --- imagekit/exceptions.py | 6 ++++++ imagekit/templatetags/imagekit_tags.py | 9 +-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index d3595b4d..55cf144f 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -1,3 +1,9 @@ +class AlreadyRegistered(Exception): + pass + + +class NotRegistered(Exception): + pass class UnknownExtensionError(Exception): diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 90a55844..16fce13f 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -2,20 +2,13 @@ from django import template from django.utils.safestring import mark_safe +from ..exceptions import AlreadyRegistered, NotRegistered from ..files import ImageSpecFile register = template.Library() -class AlreadyRegistered(Exception): - pass - - -class NotRegistered(Exception): - pass - - class SpecRegistry(object): def __init__(self): self._specs = {} From 116b0bc0c513a6603d459002dbb4faa89072c703 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 21:58:22 -0400 Subject: [PATCH 021/527] Move spec classes to specs module --- imagekit/__init__.py | 2 +- imagekit/{base.py => specs.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename imagekit/{base.py => specs.py} (100%) diff --git a/imagekit/__init__.py b/imagekit/__init__.py index ee903d93..f4fd2271 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,5 +1,5 @@ from . import conf -from .base import ImageSpec +from .specs import ImageSpec __title__ = 'django-imagekit' diff --git a/imagekit/base.py b/imagekit/specs.py similarity index 100% rename from imagekit/base.py rename to imagekit/specs.py From 99ba61d6053d12c5c02b0a28d0d8c8ffe21bd8b1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 22:02:29 -0400 Subject: [PATCH 022/527] Move spec registry --- imagekit/specs.py | 27 +++++++++++++++++++++++- imagekit/templatetags/imagekit_tags.py | 29 +------------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/imagekit/specs.py b/imagekit/specs.py index 30b34cc4..a81b82c6 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -2,7 +2,7 @@ from hashlib import md5 import os import pickle -from .exceptions import UnknownExtensionError +from .exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered from .imagecache.backends import get_default_image_cache_backend from .imagecache.strategies import StrategyWrapper from .lib import StringIO @@ -11,6 +11,31 @@ suggest_extension) +class SpecRegistry(object): + def __init__(self): + self._specs = {} + + def register(self, id, spec): + if id in self._specs: + raise AlreadyRegistered('The spec with id %s is already registered' % id) + self._specs[id] = spec + + def unregister(self, id, spec): + try: + del self._specs[id] + except KeyError: + raise NotRegistered('The spec with id %s is not registered' % id) + + def get_spec(self, id): + try: + return self._specs[id] + except KeyError: + raise NotRegistered('The spec with id %s is not registered' % id) + + +spec_registry = SpecRegistry() + + class BaseImageSpec(object): processors = None format = None diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 16fce13f..938a53bf 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,39 +1,12 @@ -import os from django import template from django.utils.safestring import mark_safe - -from ..exceptions import AlreadyRegistered, NotRegistered from ..files import ImageSpecFile +from ..specs import spec_registry register = template.Library() -class SpecRegistry(object): - def __init__(self): - self._specs = {} - - def register(self, id, spec): - if id in self._specs: - raise AlreadyRegistered('The spec with id %s is already registered' % id) - self._specs[id] = spec - - def unregister(self, id, spec): - try: - del self._specs[id] - except KeyError: - raise NotRegistered('The spec with id %s is not registered' % id) - - def get_spec(self, id): - try: - return self._specs[id] - except KeyError: - raise NotRegistered('The spec with id %s is not registered' % id) - - -spec_registry = SpecRegistry() - - class ImageSpecFileHtmlWrapper(object): def __init__(self, image_spec_file): self._image_spec_file = image_spec_file From f289ff31996286cb992c869e92e7fe774b2c6328 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 22:56:26 -0400 Subject: [PATCH 023/527] Back ImageSpecFields with spec registry This marks a major step towards centralizing some of the "spec" logic and creating a single access point for them. Because `ImageSpecFields` are just alternative interfaces for defining and registering specs, they can be accessed and overridden in the same manner as other specs (like those used by template tags): via the spec registry. --- imagekit/models/fields/__init__.py | 37 +++++++++++-------- imagekit/specs.py | 58 ++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 34af0c73..2747ebf3 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -8,34 +8,31 @@ from ..receivers import configure_receivers from ...base import ImageSpec from ...utils import suggest_extension +from ...specs import SpecHost -class ImageSpecField(object): +class ImageSpecField(SpecHost): """ The heart and soul of the ImageKit library, ImageSpecField allows you to add variants of uploaded images to your models. """ def __init__(self, processors=None, format=None, options=None, - image_field=None, storage=None, autoconvert=True, - image_cache_backend=None, image_cache_strategy=None): + image_field=None, storage=None, autoconvert=None, + image_cache_backend=None, image_cache_strategy=None, spec=None, + id=None): # The spec accepts a callable value for processors, but it # takes different arguments than the callable that ImageSpecField # expects, so we create a partial application and pass that instead. # TODO: Should we change the signatures to match? Even if `instance` is not part of the signature, it's accessible through the source file object's instance property. - p = lambda file: processors(instance=file.instance, file=file) if \ - callable(processors) else processors - - self.spec = ImageSpec( - processors=p, - format=format, - options=options, - storage=storage, - autoconvert=autoconvert, - image_cache_backend=image_cache_backend, - image_cache_strategy=image_cache_strategy, - ) + p = lambda file: processors(instance=file.instance, + file=file) if callable(processors) else processors + + SpecHost.__init__(self, processors=p, format=format, + options=options, storage=storage, autoconvert=autoconvert, + image_cache_backend=image_cache_backend, + image_cache_strategy=image_cache_strategy, spec=spec, id=id) self.image_field = image_field @@ -59,6 +56,16 @@ def contribute_to_class(self, cls, name): setattr(cls, '_ik', ik) ik.spec_fields.append(name) + # Generate a spec_id to register the spec with. The default spec id is + # ":_" + if not self.spec_id: + self.spec_id = (u'%s:%s_%s' % (cls._meta.app_label, + cls._meta.object_name, name)).lower() + + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + self.register_spec(self.spec_id) + # Register the field with the image_cache_backend try: self.spec.image_cache_backend.register_field(cls, self, name) diff --git a/imagekit/specs.py b/imagekit/specs.py index a81b82c6..d2e0cba4 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -164,3 +164,61 @@ def generate_file(self, filename, source_file, save=True): storage.save(filename, content) return content + + +class SpecHost(object): + """ + An object that ostensibly has a spec attribute but really delegates to the + spec registry. + + """ + def __init__(self, processors=None, format=None, options=None, + storage=None, autoconvert=None, image_cache_backend=None, + image_cache_strategy=None, spec=None, id=None): + + if spec: + if any([processors, format, options, storage, autoconvert, + image_cache_backend, image_cache_strategy]): + raise TypeError('You can provide either an image spec or' + ' arguments for the ImageSpec constructor, but not both.') + else: + spec = ImageSpec( + processors=processors, + format=format, + options=options, + storage=storage, + autoconvert=autoconvert, + image_cache_backend=image_cache_backend, + image_cache_strategy=image_cache_strategy, + ) + + self._original_spec = spec + self.spec_id = None + + if id: + # If an id is given, register the spec immediately. + self.register_spec(id) + + def register_spec(self, id): + """ + Registers the spec with the specified id. Useful for when the id isn't + known when the instance is constructed (e.g. for ImageSpecFields whose + generated `spec_id`s are only known when they are contributed to a + class) + + """ + self.spec_id = id + spec_registry.register(id, self._original_spec) + + @property + def spec(self): + """ + Look up the spec by the spec id. We do this (instead of storing the + spec as an attribute) so that users can override apps' specs--without + having to edit model definitions--simply by registering another spec + with the same id. + + """ + if not getattr(self, 'spec_id', None): + raise Exception('Object %s has no spec id.' % self) + return spec_registry.get_spec(self.spec_id) From 82d0e4be73993ed2fbb91769788fa0496989db14 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:03:22 -0400 Subject: [PATCH 024/527] Remove unused imports --- imagekit/models/fields/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 2747ebf3..73969dcf 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,8 +1,6 @@ import os from django.db import models -from django.db.models.signals import post_init, post_save, post_delete - from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor, ImageKitMeta from ..receivers import configure_receivers From 56c66f48833e5a36a6f65209d5b56a2391682882 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:15:16 -0400 Subject: [PATCH 025/527] Back ProcessedImageField with spec registry --- imagekit/models/fields/__init__.py | 12 +++++++----- imagekit/specs.py | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 73969dcf..f0e10af2 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -30,7 +30,8 @@ def __init__(self, processors=None, format=None, options=None, SpecHost.__init__(self, processors=p, format=format, options=options, storage=storage, autoconvert=autoconvert, image_cache_backend=image_cache_backend, - image_cache_strategy=image_cache_strategy, spec=spec, id=id) + image_cache_strategy=image_cache_strategy, spec=spec, + spec_id=id) self.image_field = image_field @@ -71,7 +72,7 @@ def contribute_to_class(self, cls, name): pass -class ProcessedImageField(models.ImageField): +class ProcessedImageField(models.ImageField, SpecHost): """ ProcessedImageField is an ImageField that runs processors on the uploaded image *before* saving it to storage. This is in contrast to specs, which @@ -83,7 +84,7 @@ class ProcessedImageField(models.ImageField): def __init__(self, processors=None, format=None, options=None, verbose_name=None, name=None, width_field=None, height_field=None, - autoconvert=True, **kwargs): + autoconvert=True, spec=None, spec_id=None, **kwargs): """ The ProcessedImageField constructor accepts all of the arguments that the :class:`django.db.models.ImageField` constructor accepts, as well @@ -91,10 +92,11 @@ def __init__(self, processors=None, format=None, options=None, :class:`imagekit.models.ImageSpecField`. """ + SpecHost.__init__(self, processors=processors, format=format, + options=options, autoconvert=autoconvert, spec=spec, + spec_id=spec_id) models.ImageField.__init__(self, verbose_name, name, width_field, height_field, **kwargs) - self.spec = ImageSpec(processors, format=format, options=options, - autoconvert=autoconvert) def get_filename(self, filename): filename = os.path.normpath(self.storage.get_valid_name( diff --git a/imagekit/specs.py b/imagekit/specs.py index d2e0cba4..b4ea37b1 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -174,7 +174,7 @@ class SpecHost(object): """ def __init__(self, processors=None, format=None, options=None, storage=None, autoconvert=None, image_cache_backend=None, - image_cache_strategy=None, spec=None, id=None): + image_cache_strategy=None, spec=None, spec_id=None): if spec: if any([processors, format, options, storage, autoconvert, @@ -195,9 +195,9 @@ def __init__(self, processors=None, format=None, options=None, self._original_spec = spec self.spec_id = None - if id: + if spec_id: # If an id is given, register the spec immediately. - self.register_spec(id) + self.register_spec(spec_id) def register_spec(self, id): """ From ce084482079b5397c9275b33d7b909beeb569af7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:22:25 -0400 Subject: [PATCH 026/527] Rename `register_spec()` to `set_spec_id()` --- imagekit/models/fields/__init__.py | 8 ++++---- imagekit/specs.py | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index f0e10af2..ba1d87e0 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -57,13 +57,13 @@ def contribute_to_class(self, cls, name): # Generate a spec_id to register the spec with. The default spec id is # ":_" - if not self.spec_id: + if not getattr(self, 'spec_id', None): self.spec_id = (u'%s:%s_%s' % (cls._meta.app_label, cls._meta.object_name, name)).lower() - # Register the spec with the id. This allows specs to be overridden - # later, from outside of the model definition. - self.register_spec(self.spec_id) + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + self.set_spec_id(self.spec_id) # Register the field with the image_cache_backend try: diff --git a/imagekit/specs.py b/imagekit/specs.py index b4ea37b1..49affad9 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -193,18 +193,17 @@ def __init__(self, processors=None, format=None, options=None, ) self._original_spec = spec - self.spec_id = None if spec_id: - # If an id is given, register the spec immediately. - self.register_spec(spec_id) + self.set_spec_id(spec_id) - def register_spec(self, id): + def set_spec_id(self, id): """ - Registers the spec with the specified id. Useful for when the id isn't + Sets the spec id for this object. Useful for when the id isn't known when the instance is constructed (e.g. for ImageSpecFields whose generated `spec_id`s are only known when they are contributed to a - class) + class). If the object was initialized with a spec, it will be registered + under the provided id. """ self.spec_id = id From 5a1dd0c459a32c57dc05b6872d92f83c2fe5f6e0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:27:19 -0400 Subject: [PATCH 027/527] Don't require spec to be created up-front --- imagekit/specs.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/imagekit/specs.py b/imagekit/specs.py index 49affad9..2d4b4008 100644 --- a/imagekit/specs.py +++ b/imagekit/specs.py @@ -176,21 +176,22 @@ def __init__(self, processors=None, format=None, options=None, storage=None, autoconvert=None, image_cache_backend=None, image_cache_strategy=None, spec=None, spec_id=None): - if spec: - if any([processors, format, options, storage, autoconvert, - image_cache_backend, image_cache_strategy]): + spec_args = dict( + processors=processors, + format=format, + options=options, + storage=storage, + autoconvert=autoconvert, + image_cache_backend=image_cache_backend, + image_cache_strategy=image_cache_strategy, + ) + + if any(v is not None for v in spec_args.values()): + if spec: raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') - else: - spec = ImageSpec( - processors=processors, - format=format, - options=options, - storage=storage, - autoconvert=autoconvert, - image_cache_backend=image_cache_backend, - image_cache_strategy=image_cache_strategy, - ) + else: + spec = ImageSpec(**spec_args) self._original_spec = spec From 436a73dc9a994ebbedff4c00ea3b1f403202d56a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:28:55 -0400 Subject: [PATCH 028/527] Remove image cache backend field registration --- imagekit/models/fields/__init__.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index ba1d87e0..f7490402 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -65,12 +65,6 @@ def contribute_to_class(self, cls, name): # later, from outside of the model definition. self.set_spec_id(self.spec_id) - # Register the field with the image_cache_backend - try: - self.spec.image_cache_backend.register_field(cls, self, name) - except AttributeError: - pass - class ProcessedImageField(models.ImageField, SpecHost): """ From 667f0cc08e85257d6fe38b19150e49bf926b2581 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:41:20 -0400 Subject: [PATCH 029/527] Simplify IMAGEKIT_CACHE_BACKEND setting --- imagekit/conf.py | 6 ++++++ imagekit/imagecache/backends.py | 4 +--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 2767e6b0..5780235f 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -1,4 +1,5 @@ from appconf import AppConf +from django.conf import settings from .imagecache.actions import validate_now, clear_now @@ -8,3 +9,8 @@ class ImageKitConf(AppConf): CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'ik-' DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' + + def configure_cache_backend(self, value): + if value is None: + value = 'django.core.cache.backends.dummy.DummyCache' if settings.DEBUG else 'default' + return value diff --git a/imagekit/imagecache/backends.py b/imagekit/imagecache/backends.py index cbb7f5d5..c7339ab6 100644 --- a/imagekit/imagecache/backends.py +++ b/imagekit/imagecache/backends.py @@ -1,6 +1,5 @@ from ..utils import get_singleton from django.core.cache import get_cache -from django.core.cache.backends.dummy import DummyCache from django.core.exceptions import ImproperlyConfigured @@ -23,8 +22,7 @@ class CachedValidationBackend(object): def cache(self): if not getattr(self, '_cache', None): from django.conf import settings - alias = settings.IMAGEKIT_CACHE_BACKEND - self._cache = get_cache(alias) if alias else DummyCache(None, {}) + self._cache = get_cache(settings.IMAGEKIT_CACHE_BACKEND) return self._cache def get_key(self, file): From 06e5f459046b1b8c4dd59fb4c3e13f9c1af0e668 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 4 Oct 2012 23:41:32 -0400 Subject: [PATCH 030/527] Remove unused imports --- imagekit/conf.py | 1 - imagekit/models/fields/__init__.py | 1 - 2 files changed, 2 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 5780235f..d245b50b 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -1,6 +1,5 @@ from appconf import AppConf from django.conf import settings -from .imagecache.actions import validate_now, clear_now class ImageKitConf(AppConf): diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index f7490402..fb3f78d5 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -4,7 +4,6 @@ from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor, ImageKitMeta from ..receivers import configure_receivers -from ...base import ImageSpec from ...utils import suggest_extension from ...specs import SpecHost From fe803f898163856af13e6f85c8a3e81cce03ccb7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 10 Oct 2012 00:18:54 -0400 Subject: [PATCH 031/527] Beginning to move functionality into "sources" Before this is applied, we're going to have to make it so that the image cache strategies are passed the source file, not the other file. --- imagekit/models/fields/__init__.py | 24 ++--- imagekit/models/fields/utils.py | 23 ----- imagekit/models/receivers.py | 51 ----------- imagekit/{specs.py => specs/__init__.py} | 19 ++++ imagekit/specs/signals.py | 5 ++ imagekit/specs/sources.py | 107 +++++++++++++++++++++++ imagekit/utils.py | 8 -- 7 files changed, 139 insertions(+), 98 deletions(-) delete mode 100644 imagekit/models/receivers.py rename imagekit/{specs.py => specs/__init__.py} (91%) create mode 100644 imagekit/specs/signals.py create mode 100644 imagekit/specs/sources.py diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index fb3f78d5..92a25d30 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,11 +1,12 @@ import os from django.db import models -from .files import ProcessedImageFieldFile -from .utils import ImageSpecFileDescriptor, ImageKitMeta +from ..files import ProcessedImageFieldFile +from .utils import ImageSpecFileDescriptor from ..receivers import configure_receivers from ...utils import suggest_extension -from ...specs import SpecHost +from ...specs import SpecHost, spec_registry +from ...specs.sources import ImageFieldSpecSource class ImageSpecField(SpecHost): @@ -40,19 +41,6 @@ def storage(self): def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) - try: - # Make sure we don't modify an inherited ImageKitMeta instance - ik = cls.__dict__['ik'] - except KeyError: - try: - base = getattr(cls, '_ik') - except AttributeError: - ik = ImageKitMeta() - else: - # Inherit all the spec fields. - ik = ImageKitMeta(base.spec_fields) - setattr(cls, '_ik', ik) - ik.spec_fields.append(name) # Generate a spec_id to register the spec with. The default spec id is # ":_" @@ -64,6 +52,10 @@ def contribute_to_class(self, cls, name): # later, from outside of the model definition. self.set_spec_id(self.spec_id) + # Register the model and field as a source for this spec id + spec_registry.add_source(self.spec_id, + ImageFieldSpecSource(cls, self.image_field)) + class ProcessedImageField(models.ImageField, SpecHost): """ diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 1b3ccaa1..3014b53e 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,29 +1,6 @@ from .files import ImageSpecFieldFile -class BoundImageKitMeta(object): - def __init__(self, instance, spec_fields): - self.instance = instance - self.spec_fields = spec_fields - - @property - def spec_files(self): - return [getattr(self.instance, n) for n in self.spec_fields] - - -class ImageKitMeta(object): - def __init__(self, spec_fields=None): - self.spec_fields = list(spec_fields) if spec_fields else [] - - def __get__(self, instance, owner): - if instance is None: - return self - else: - ik = BoundImageKitMeta(instance, self.spec_fields) - setattr(instance, '_ik', ik) - return ik - - class ImageSpecFileDescriptor(object): def __init__(self, field, attname): self.attname = attname diff --git a/imagekit/models/receivers.py b/imagekit/models/receivers.py deleted file mode 100644 index 67960f7e..00000000 --- a/imagekit/models/receivers.py +++ /dev/null @@ -1,51 +0,0 @@ -from django.db.models.signals import post_init, post_save, post_delete -from ..utils import ik_model_receiver - - -def update_source_hashes(instance): - """ - Stores hashes of the source image files so that they can be compared - later to see whether the source image has changed (and therefore whether - the spec file needs to be regenerated). - - """ - instance._ik._source_hashes = dict((f.attname, hash(f.source_file)) \ - for f in instance._ik.spec_files) - return instance._ik._source_hashes - - -@ik_model_receiver -def post_save_receiver(sender, instance=None, created=False, raw=False, **kwargs): - if not raw: - old_hashes = instance._ik._source_hashes.copy() - new_hashes = update_source_hashes(instance) - for attname in instance._ik.spec_fields: - file = getattr(instance, attname) - if created: - file.field.spec.image_cache_strategy.invoke_callback('source_create', file) - elif old_hashes[attname] != new_hashes[attname]: - file.field.spec.image_cache_strategy.invoke_callback('source_change', file) - - -@ik_model_receiver -def post_delete_receiver(sender, instance=None, **kwargs): - for spec_file in instance._ik.spec_files: - spec_file.field.spec.image_cache_strategy.invoke_callback('source_delete', spec_file) - - -@ik_model_receiver -def post_init_receiver(sender, instance, **kwargs): - update_source_hashes(instance) - - -def configure_receivers(): - # Connect the signals. We have to listen to every model (not just those - # with IK fields) and filter in our receivers because of a Django issue with - # abstract base models. - # Related: - # https://github.com/jdriscoll/django-imagekit/issues/126 - # https://code.djangoproject.com/ticket/9318 - uid = 'ik_spec_field_receivers' - post_init.connect(post_init_receiver, dispatch_uid=uid) - post_save.connect(post_save_receiver, dispatch_uid=uid) - post_delete.connect(post_delete_receiver, dispatch_uid=uid) diff --git a/imagekit/specs.py b/imagekit/specs/__init__.py similarity index 91% rename from imagekit/specs.py rename to imagekit/specs/__init__.py index 2d4b4008..160612ff 100644 --- a/imagekit/specs.py +++ b/imagekit/specs/__init__.py @@ -1,3 +1,4 @@ +from collections import defaultdict from django.conf import settings from hashlib import md5 import os @@ -7,6 +8,7 @@ from .imagecache.strategies import StrategyWrapper from .lib import StringIO from .processors import ProcessorPipeline +from .signals import source_created, source_changed, source_deleted from .utils import (open_image, extension_to_format, IKContentFile, img_to_fobj, suggest_extension) @@ -14,12 +16,29 @@ class SpecRegistry(object): def __init__(self): self._specs = {} + self._sources = defaultdict(list) def register(self, id, spec): if id in self._specs: raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec + def add_source(self, id, source): + self._sources[id].append(source) + source_created.connect(receiver, sender, weak, dispatch_uid) + source_changed.connect(receiver, sender, weak, dispatch_uid) + source_deleted.connect(receiver, sender, weak, dispatch_uid) + + def source_receiver(self, source, source_file): + # Get a list of specs that use this source. + ids = (k for k, v in self._sources.items() if source in v) + specs = (self.get_spec(id) for id in ids) + for spec in specs: + spec.image_cache_strategy.invoke_callback(..., source_file) + + def get_sources(self, id): + return self._sources[id] + def unregister(self, id, spec): try: del self._specs[id] diff --git a/imagekit/specs/signals.py b/imagekit/specs/signals.py new file mode 100644 index 00000000..7c0888c2 --- /dev/null +++ b/imagekit/specs/signals.py @@ -0,0 +1,5 @@ +from django.dispatch import Signal + +source_created = Signal(providing_args=[]) +source_changed = Signal() +source_deleted = Signal() diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py new file mode 100644 index 00000000..88e61562 --- /dev/null +++ b/imagekit/specs/sources.py @@ -0,0 +1,107 @@ +from django.db.models.signals import post_init, post_save, post_delete +from django.utils.functional import wraps +from .signals import source_created, source_changed, source_deleted + + +def ik_model_receiver(fn): + """ + A method decorator that filters out signals coming from models that don't + have fields that function as ImageFieldSpecSources + + """ + @wraps(fn) + def receiver(self, sender, **kwargs): + if sender in (src.model_class for src in self._sources): + fn(sender, **kwargs) + return receiver + + +class ModelSignalRouter(object): + def __init__(self): + self._sources = [] + uid = 'ik_spec_field_receivers' + post_init.connect(self.post_init_receiver, dispatch_uid=uid) + post_save.connect(self.post_save_receiver, dispatch_uid=uid) + post_delete.connect(self.post_delete_receiver, dispatch_uid=uid) + + def add(self, source): + self._sources.append(source) + + def init_instance(self, instance): + instance._ik = getattr(instance, '_ik', {}) + + def update_source_hashes(self, instance): + """ + Stores hashes of the source image files so that they can be compared + later to see whether the source image has changed (and therefore whether + the spec file needs to be regenerated). + + """ + self.init_instance(instance) + instance._ik['source_hashes'] = dict((k, hash(v.source_file)) + for k, v in self.get_field_dict(instance).items()) + return instance._ik['source_hashes'] + + def get_field_dict(self, instance): + """ + Returns the source fields for the given instance, in a dictionary whose + keys are the field names and values are the fields themselves. + + """ + return dict((src.image_field, getattr(instance, src.image_field)) for + src in self._sources if src.model_class is instance.__class__) + + @ik_model_receiver + def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): + if not raw: + self.init_instance(instance) + old_hashes = instance._ik.get('source_hashes', {}).copy() + new_hashes = self.update_source_hashes(instance) + for attname, file in self.get_field_dict(instance).items(): + if created: + self.dispatch_signal(source_created, sender, file) + elif old_hashes[attname] != new_hashes[attname]: + self.dispatch_signal(source_changed, sender, file) + + @ik_model_receiver + def post_delete_receiver(self, sender, instance=None, **kwargs): + for attname, file in self.get_field_dict(instance): + self.dispatch_signal(source_deleted, sender, file) + + @classmethod + @ik_model_receiver + def post_init_receiver(self, sender, instance, **kwargs): + self.update_source_hashes(instance) + + def dispatch_signal(self, signal, model_class, file): + """ + Dispatch the signal for each of the matching sources. Note that more + than one source can have the same model and image_field; it's important + that we dispatch the signal for each. + + """ + for source in self._sources: + if source.model_class is model_class and source.image_field == file.attname: + signal.send(sender=source, source_file=file) + + +class ImageFieldSpecSource(object): + def __init__(self, model_class, image_field): + """ + Good design would dictate that this instance would be responsible for + watching for changes for the provided field. However, due to a bug in + Django, we can't do that without leaving abstract base models (which + don't trigger signals) in the lurch. So instead, we do all signal + handling through the signal router. + + Related: + https://github.com/jdriscoll/django-imagekit/issues/126 + https://code.djangoproject.com/ticket/9318 + + """ + self.model_class = model_class + self.image_field = image_field + signal_router.add(self) + + +signal_router = ModelSignalRouter() diff --git a/imagekit/utils.py b/imagekit/utils.py index fb600354..07f05e52 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -399,14 +399,6 @@ def get_singleton(class_path, desc): return instance -def ik_model_receiver(fn): - @wraps(fn) - def receiver(sender, **kwargs): - if getattr(sender, '_ik', None): - fn(sender, **kwargs) - return receiver - - def autodiscover(): """ Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when From 8a35b3a3ddaaa4e052da80f2b087487eeaace459 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 12 Oct 2012 22:36:13 -0400 Subject: [PATCH 032/527] Registration and connection of sources --- imagekit/models/fields/__init__.py | 15 +++---- imagekit/specs/__init__.py | 64 +++++++++++++++++------------- imagekit/specs/sources.py | 9 ++--- 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 92a25d30..517c94ec 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,11 +1,11 @@ import os from django.db import models -from ..files import ProcessedImageFieldFile +from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor -from ..receivers import configure_receivers +from ... import specs from ...utils import suggest_extension -from ...specs import SpecHost, spec_registry +from ...specs import SpecHost from ...specs.sources import ImageFieldSpecSource @@ -52,9 +52,9 @@ def contribute_to_class(self, cls, name): # later, from outside of the model definition. self.set_spec_id(self.spec_id) - # Register the model and field as a source for this spec id - spec_registry.add_source(self.spec_id, - ImageFieldSpecSource(cls, self.image_field)) + # Add the model and field as a source for this spec id + specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field), + self.spec_id) class ProcessedImageField(models.ImageField, SpecHost): @@ -97,6 +97,3 @@ def get_filename(self, filename): pass else: add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$']) - - -configure_receivers() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 160612ff..eb98975c 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,44 +1,35 @@ -from collections import defaultdict from django.conf import settings from hashlib import md5 import os import pickle -from .exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered -from .imagecache.backends import get_default_image_cache_backend -from .imagecache.strategies import StrategyWrapper -from .lib import StringIO -from .processors import ProcessorPipeline from .signals import source_created, source_changed, source_deleted -from .utils import (open_image, extension_to_format, IKContentFile, img_to_fobj, - suggest_extension) +from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered +from ..imagecache.backends import get_default_image_cache_backend +from ..imagecache.strategies import StrategyWrapper +from ..lib import StringIO +from ..processors import ProcessorPipeline +from ..utils import (open_image, extension_to_format, IKContentFile, + img_to_fobj, suggest_extension) class SpecRegistry(object): + signals = { + source_created: 'source_created', + source_changed: 'source_changed', + source_deleted: 'source_deleted', + } + def __init__(self): self._specs = {} - self._sources = defaultdict(list) + self._sources = {} + for signal in self.signals.keys(): + signal.connect(lambda *a, **k: self.source_receiver(signal, *a, **k)) def register(self, id, spec): if id in self._specs: raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec - def add_source(self, id, source): - self._sources[id].append(source) - source_created.connect(receiver, sender, weak, dispatch_uid) - source_changed.connect(receiver, sender, weak, dispatch_uid) - source_deleted.connect(receiver, sender, weak, dispatch_uid) - - def source_receiver(self, source, source_file): - # Get a list of specs that use this source. - ids = (k for k, v in self._sources.items() if source in v) - specs = (self.get_spec(id) for id in ids) - for spec in specs: - spec.image_cache_strategy.invoke_callback(..., source_file) - - def get_sources(self, id): - return self._sources[id] - def unregister(self, id, spec): try: del self._specs[id] @@ -51,8 +42,22 @@ def get_spec(self, id): except KeyError: raise NotRegistered('The spec with id %s is not registered' % id) + def add_source(self, source, spec_id): + """ + Associates a source with a spec id + + """ + if source not in self._sources: + self._sources[source] = set() + self._sources[source].add(spec_id) + + def source_receiver(self, signal, source, source_file): + if source not in self._sources: + return -spec_registry = SpecRegistry() + callback_name = self._signals[signal] + for spec in (self.get_spec(id) for id in self._sources[source]): + spec.image_cache_strategy.invoke_callback(callback_name, source_file) class BaseImageSpec(object): @@ -227,7 +232,7 @@ def set_spec_id(self, id): """ self.spec_id = id - spec_registry.register(id, self._original_spec) + registry.register(id, self._original_spec) @property def spec(self): @@ -240,4 +245,7 @@ def spec(self): """ if not getattr(self, 'spec_id', None): raise Exception('Object %s has no spec id.' % self) - return spec_registry.get_spec(self.spec_id) + return registry.get_spec(self.spec_id) + + +registry = SpecRegistry() diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 88e61562..82b118ba 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -12,7 +12,7 @@ def ik_model_receiver(fn): @wraps(fn) def receiver(self, sender, **kwargs): if sender in (src.model_class for src in self._sources): - fn(sender, **kwargs) + fn(self, sender=sender, **kwargs) return receiver @@ -38,8 +38,8 @@ def update_source_hashes(self, instance): """ self.init_instance(instance) - instance._ik['source_hashes'] = dict((k, hash(v.source_file)) - for k, v in self.get_field_dict(instance).items()) + instance._ik['source_hashes'] = dict((attname, hash(file_field)) + for attname, file_field in self.get_field_dict(instance).items()) return instance._ik['source_hashes'] def get_field_dict(self, instance): @@ -68,9 +68,8 @@ def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance): self.dispatch_signal(source_deleted, sender, file) - @classmethod @ik_model_receiver - def post_init_receiver(self, sender, instance, **kwargs): + def post_init_receiver(self, sender, instance=None, **kwargs): self.update_source_hashes(instance) def dispatch_signal(self, signal, model_class, file): From a59330cf2c17065b2d590f8e340b85cd72a514ab Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 12 Oct 2012 23:12:05 -0400 Subject: [PATCH 033/527] Add class description --- imagekit/specs/sources.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 82b118ba..807ee2a0 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -17,6 +17,12 @@ def receiver(self, sender, **kwargs): class ModelSignalRouter(object): + """ + Handles signals dispatched by models and relays them to the spec sources + that represent those models. + + """ + def __init__(self): self._sources = [] uid = 'ik_spec_field_receivers' From 440fcb19efb34ceff1665740d5bb0a5cfa219c1a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 12 Oct 2012 23:43:51 -0400 Subject: [PATCH 034/527] Correct signal relaying --- imagekit/specs/__init__.py | 7 ++++--- imagekit/specs/sources.py | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index eb98975c..e29cdb63 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -23,7 +23,7 @@ def __init__(self): self._specs = {} self._sources = {} for signal in self.signals.keys(): - signal.connect(lambda *a, **k: self.source_receiver(signal, *a, **k)) + signal.connect(self.source_receiver) def register(self, id, spec): if id in self._specs: @@ -51,11 +51,12 @@ def add_source(self, source, spec_id): self._sources[source] = set() self._sources[source].add(spec_id) - def source_receiver(self, signal, source, source_file): + def source_receiver(self, sender, source_file, signal, **kwargs): + source = sender if source not in self._sources: return - callback_name = self._signals[signal] + callback_name = self.signals[signal] for spec in (self.get_spec(id) for id in self._sources[source]): spec.image_cache_strategy.invoke_callback(callback_name, source_file) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 807ee2a0..183180d8 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -65,20 +65,20 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(source_created, sender, file) + self.dispatch_signal(source_created, file, sender) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, sender, file) + self.dispatch_signal(source_changed, file, sender) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance): - self.dispatch_signal(source_deleted, sender, file) + self.dispatch_signal(source_deleted, file, sender) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): self.update_source_hashes(instance) - def dispatch_signal(self, signal, model_class, file): + def dispatch_signal(self, signal, file, model_class): """ Dispatch the signal for each of the matching sources. Note that more than one source can have the same model and image_field; it's important @@ -86,7 +86,8 @@ def dispatch_signal(self, signal, model_class, file): """ for source in self._sources: - if source.model_class is model_class and source.image_field == file.attname: + # TODO: Is it okay to require a field attribute on our file? + if source.model_class is model_class and source.image_field == file.field.attname: signal.send(sender=source, source_file=file) From cedd744e32a8e76681fb33f04d4847b2c81c7253 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 13 Oct 2012 00:22:30 -0400 Subject: [PATCH 035/527] Add description of registry --- imagekit/specs/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e29cdb63..e3a44077 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -13,6 +13,16 @@ class SpecRegistry(object): + """ + An object for registering specs and sources. The two are associated with + eachother via a string id. We do this (as opposed to associating them + directly by, for example, putting a ``sources`` attribute on specs) so that + specs can be overridden without losing the associated sources. That way, + a distributable app can define its own specs without locking the users of + the app into it. + + """ + signals = { source_created: 'source_created', source_changed: 'source_changed', From 7447d147d4da1eff12138ba7df14e79a5f253176 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 13 Oct 2012 01:15:42 -0400 Subject: [PATCH 036/527] Wire up source events to specs (and image cache strategies) Also change signal names to past tense to match convention. --- imagekit/imagecache/strategies.py | 14 +++++------ imagekit/specs/__init__.py | 39 ++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index 7ec72528..e44929a4 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -8,13 +8,13 @@ class Pessimistic(object): """ - def on_access(self, file): + def on_accessed(self, file): validate_now(file) - def on_source_delete(self, file): + def on_source_deleted(self, file): clear_now(file) - def on_source_change(self, file): + def on_source_changed(self, file): validate_now(file) @@ -25,13 +25,13 @@ class Optimistic(object): """ - def on_source_create(self, file): + def on_source_created(self, file): validate_now(file) - def on_source_delete(self, file): + def on_source_deleted(self, file): clear_now(file) - def on_source_change(self, file): + def on_source_changed(self, file): validate_now(file) @@ -52,6 +52,6 @@ def __init__(self, strategy): self._wrapped = strategy def invoke_callback(self, name, *args, **kwargs): - func = getattr(self._wrapped, 'on_%s' % name, None) + func = getattr(self._wrapped, name, None) if func: func(*args, **kwargs) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e3a44077..7b5b0df7 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,6 +4,7 @@ import pickle from .signals import source_created, source_changed, source_deleted from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered +from ..files import ImageSpecFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..lib import StringIO @@ -23,16 +24,16 @@ class SpecRegistry(object): """ - signals = { - source_created: 'source_created', - source_changed: 'source_changed', - source_deleted: 'source_deleted', - } + _source_signals = [ + source_created, + source_changed, + source_deleted, + ] def __init__(self): self._specs = {} self._sources = {} - for signal in self.signals.keys(): + for signal in self._source_signals: signal.connect(self.source_receiver) def register(self, id, spec): @@ -62,13 +63,21 @@ def add_source(self, source, spec_id): self._sources[source].add(spec_id) def source_receiver(self, sender, source_file, signal, **kwargs): + """ + Redirects signals dispatched on sources to the appropriate specs. + + """ source = sender if source not in self._sources: return - callback_name = self.signals[signal] for spec in (self.get_spec(id) for id in self._sources[source]): - spec.image_cache_strategy.invoke_callback(callback_name, source_file) + event_name = { + source_created: 'source_created', + source_changed: 'source_changed', + source_deleted: 'source_deleted', + } + spec._handle_source_event(event_name, source_file) class BaseImageSpec(object): @@ -176,6 +185,20 @@ def __init__(self, processors=None, format=None, options=None, self.image_cache_backend = image_cache_backend or self.image_cache_backend or get_default_image_cache_backend() self.image_cache_strategy = StrategyWrapper(image_cache_strategy or self.image_cache_strategy) + # TODO: Can we come up with a better name for this? "process" may cause confusion with processors' process() + def apply(self, source_file): + """ + Creates a file object that represents the combination of a spec and + source file. + + """ + return ImageSpecFile(self, source_file) + + # TODO: I don't like this interface. Is there a standard Python one? pubsub? + def _handle_source_event(self, event_name, source_file): + file = self.apply(source_file) + self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) + def generate_file(self, filename, source_file, save=True): """ Generates a new image file by processing the source file and returns From 7ce05f468a3b6a7f0d9f325ec3a6b952f1da04a5 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 14 Oct 2012 15:41:35 -0400 Subject: [PATCH 037/527] Pass attname to dispatch_signal This allows any file object to be used--even those that don't have a `field` attribute. For example, you could theoretically use one spec field as a source for another. --- imagekit/specs/sources.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 183180d8..389d7cba 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -65,20 +65,20 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(source_created, file, sender) + self.dispatch_signal(source_created, file, sender, attname) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, file, sender) + self.dispatch_signal(source_changed, file, sender, attname) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance): - self.dispatch_signal(source_deleted, file, sender) + self.dispatch_signal(source_deleted, file, sender, attname) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): self.update_source_hashes(instance) - def dispatch_signal(self, signal, file, model_class): + def dispatch_signal(self, signal, file, model_class, attname): """ Dispatch the signal for each of the matching sources. Note that more than one source can have the same model and image_field; it's important @@ -86,8 +86,7 @@ def dispatch_signal(self, signal, file, model_class): """ for source in self._sources: - # TODO: Is it okay to require a field attribute on our file? - if source.model_class is model_class and source.image_field == file.field.attname: + if source.model_class is model_class and source.image_field == attname: signal.send(sender=source, source_file=file) From dc84144d6badb4cf24b35abfa7e01f0bf55a1859 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 14 Oct 2012 15:52:08 -0400 Subject: [PATCH 038/527] Pass additional info with source signal --- imagekit/specs/__init__.py | 2 +- imagekit/specs/sources.py | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 7b5b0df7..a86eb958 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -62,7 +62,7 @@ def add_source(self, source, spec_id): self._sources[source] = set() self._sources[source].add(spec_id) - def source_receiver(self, sender, source_file, signal, **kwargs): + def source_receiver(self, sender, source_file, signal, info, **kwargs): """ Redirects signals dispatched on sources to the appropriate specs. diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 389d7cba..42f8c85c 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -65,20 +65,22 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(source_created, file, sender, attname) + self.dispatch_signal(source_created, file, sender, instance, + attname) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, file, sender, attname) + self.dispatch_signal(source_changed, file, sender, instance, + attname) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance): - self.dispatch_signal(source_deleted, file, sender, attname) + self.dispatch_signal(source_deleted, file, sender, instance, attname) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): self.update_source_hashes(instance) - def dispatch_signal(self, signal, file, model_class, attname): + def dispatch_signal(self, signal, file, model_class, instance, attname): """ Dispatch the signal for each of the matching sources. Note that more than one source can have the same model and image_field; it's important @@ -87,7 +89,12 @@ def dispatch_signal(self, signal, file, model_class, attname): """ for source in self._sources: if source.model_class is model_class and source.image_field == attname: - signal.send(sender=source, source_file=file) + info = dict( + source=source, + instance=instance, + field_name=attname, + ) + signal.send(sender=source, source_file=file, info=info) class ImageFieldSpecSource(object): From 461fbaef1a524456f89b1839fec28bfb96ac3717 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Sun, 14 Oct 2012 18:48:17 -0400 Subject: [PATCH 039/527] Processors no longer callable --- imagekit/models/fields/__init__.py | 9 +-------- imagekit/specs/__init__.py | 10 ++-------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 517c94ec..148212c9 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -20,14 +20,7 @@ def __init__(self, processors=None, format=None, options=None, image_cache_backend=None, image_cache_strategy=None, spec=None, id=None): - # The spec accepts a callable value for processors, but it - # takes different arguments than the callable that ImageSpecField - # expects, so we create a partial application and pass that instead. - # TODO: Should we change the signatures to match? Even if `instance` is not part of the signature, it's accessible through the source file object's instance property. - p = lambda file: processors(instance=file.instance, - file=file) if callable(processors) else processors - - SpecHost.__init__(self, processors=p, format=format, + SpecHost.__init__(self, processors=processors, format=format, options=options, storage=storage, autoconvert=autoconvert, image_cache_backend=image_cache_backend, image_cache_strategy=image_cache_strategy, spec=spec, diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index a86eb958..cdb5638b 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -92,16 +92,10 @@ def __init__(self, processors=None, format=None, options=None, autoconvert=None) self.options = options or self.options self.autoconvert = self.autoconvert if autoconvert is None else autoconvert - def get_processors(self, source_file): - processors = self.processors - if callable(processors): - processors = processors(source_file) - return processors - def get_hash(self, source_file): return md5(''.join([ source_file.name, - pickle.dumps(self.get_processors(source_file)), + pickle.dumps(self.processors), self.format, pickle.dumps(self.options), str(self.autoconvert), @@ -125,7 +119,7 @@ def process_content(self, content, filename=None, source_file=None): original_format = img.format # Run the processors - processors = self.get_processors(source_file) + processors = self.processors img = ProcessorPipeline(processors or []).process(img) options = dict(self.options or {}) From 93409c8f05b160584296e639d9cf202a86e456bc Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Sun, 14 Oct 2012 21:35:07 -0400 Subject: [PATCH 040/527] SpecRegistry's spec can be callable (spec factory) --- imagekit/specs/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index cdb5638b..d6271d77 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -47,11 +47,15 @@ def unregister(self, id, spec): except KeyError: raise NotRegistered('The spec with id %s is not registered' % id) - def get_spec(self, id): + def get_spec(self, id, **kwargs): try: - return self._specs[id] + spec = self._specs[id] except KeyError: raise NotRegistered('The spec with id %s is not registered' % id) + if callable(spec): + return spec(**kwargs) + else: + return spec def add_source(self, source, spec_id): """ @@ -71,7 +75,8 @@ def source_receiver(self, sender, source_file, signal, info, **kwargs): if source not in self._sources: return - for spec in (self.get_spec(id) for id in self._sources[source]): + for spec in (self.get_spec(id, source_file=source_file, **info) + for id in self._sources[source]): event_name = { source_created: 'source_created', source_changed: 'source_changed', From 5fe5a73cb17a55c1351fee7d57e5c56ce77b58ea Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 14 Oct 2012 22:28:48 -0400 Subject: [PATCH 041/527] Update docs This will be great when 3.0 is ready, but it'll also serve as a nice guide for us as we develop. --- README.rst | 273 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 182 insertions(+), 91 deletions(-) diff --git a/README.rst b/README.rst index 041d02d0..9b38119c 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,7 @@ -ImageKit is a Django app that helps you to add variations of uploaded images -to your models. These variations are called "specs" and can include things -like different sizes (e.g. thumbnails) and black and white versions. +ImageKit is a Django app for processing images. Need a thumbnail? A +black-and-white version of a user-uploaded image? ImageKit will make them for +you. If you need to programatically generate one image from another, you need +ImageKit. **For the complete documentation on the latest stable version of ImageKit, see** `ImageKit on RTD`_. Our `changelog is also available`_. @@ -10,10 +11,10 @@ like different sizes (e.g. thumbnails) and black and white versions. Installation ------------- +============ -1. Install `PIL`_ or `Pillow`_. If you're using an ``ImageField`` in Django, - you should have already done this. +1. Install `PIL`_ or `Pillow`_. (If you're using an ``ImageField`` in Django, + you should have already done this.) 2. ``pip install django-imagekit`` (or clone the source and put the imagekit module on your path) 3. Add ``'imagekit'`` to your ``INSTALLED_APPS`` list in your project's settings.py @@ -27,11 +28,90 @@ Installation .. _`Pillow`: http://pypi.python.org/pypi/Pillow -Adding Specs to a Model ------------------------ +Usage Overview +============== + + +Specs +----- + +You have one image and you want to do something to it to create another image. +That's the basic use case of ImageKit. But how do you tell ImageKit what to do? +By defining an "image spec." Specs are instructions for creating a new image +from an existing one, and there are a few ways to define one. The most basic +way is by defining an ``ImageSpec`` subclass: + +.. code-block:: python + + from imagekit import ImageSpec + from imagekit.processors import ResizeToFill + + class Thumbnail(ImageSpec): + processors = [ResizeToFill(100, 50)] + format = 'JPEG' + options = {'quality': 60} + +Now that you've defined a spec, it's time to use it. The nice thing about specs +is that they can be used in many different contexts. -Much like ``django.db.models.ImageField``, Specs are defined as properties -of a model class: +Sometimes, you may want to just use a spec to generate a new image file. This +might be useful, for example, in view code, or in scripts: + +.. code-block:: python + + ???????? + +More often, however, you'll want to register your spec with ImageKit: + +.. code-block:: python + + from imagekit import specs + specs.register('myapp:fancy_thumbnail', Thumbnail) + +Once a spec is registered with a unique name, you can start to take advantage of +ImageKit's powerful utilities to automatically generate images for you... + +.. note:: You might be wondering why we bother with the id string instead of + just passing the spec itself. The reason is that these ids allow users to + easily override specs defined in third party apps. That way, it doesn't + matter if "django-badblog" says its thumbnails are 200x200, you can just + register your own spec (using the same id the app uses) and have whatever + size thumbnails you want. + + +In Templates +^^^^^^^^^^^^ + +One utility ImageKit provides for processing images is a template tag: + +.. code-block:: html + + {% load imagekit %} + + {% spec 'myapp:fancy_thumbnail' source_image alt='A picture of me' %} + +Output: + +.. code-block:: html + + A picture of me + +Not generating HTML image tags? No problem. The tag also functions as an +assignment tag, providing access to the underlying file object: + +.. code-block:: html + + {% load imagekit %} + + {% spec 'myapp:fancy_thumbnail' source_image as th %} + Click to download a cool {{ th.width }} x {{ th.height }} image! + + +In Models +^^^^^^^^^ + +Specs can also be used to add ``ImageField``-like fields that expose the result +of applying a spec to another one of your model's fields: .. code-block:: python @@ -39,73 +119,111 @@ of a model class: from imagekit.models import ImageSpecField class Photo(models.Model): - original_image = models.ImageField(upload_to='photos') - formatted_image = ImageSpecField(image_field='original_image', format='JPEG', - options={'quality': 90}) + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(id='myapp:fancy_thumbnail', image_field='avatar') -Accessing the spec through a model instance will create the image and return -an ImageFile-like object (just like with a normal -``django.db.models.ImageField``): + photo = Photo.objects.all()[0] + print photo.avatar_thumbnail.url # > /static/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg + print photo.avatar_thumbnail.width # > 100 + +Since defining a spec, registering it, and using it in a single model field is +such a common usage, ImakeKit provides a shortcut that allow you to skip +writing a subclass of ``ImageSpec``: .. code-block:: python + from django.db import models + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class Photo(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}, + image_field='avatar') + photo = Photo.objects.all()[0] - photo.original_image.url # > '/media/photos/birthday.tiff' - photo.formatted_image.url # > '/media/cache/photos/birthday_formatted_image.jpeg' + print photo.avatar_thumbnail.url # > /static/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg + print photo.avatar_thumbnail.width # > 100 -Check out ``imagekit.models.ImageSpecField`` for more information. +This has the exact same behavior as before, but the spec definition is inlined. +Since no ``id`` is provided, one is automatically generated based on the app +name, model, and field. -If you only want to save the processed image (without maintaining the original), -you can use a ``ProcessedImageField``: +Specs can also be used in models to add ``ImageField``-like fields that process +a user-provided image without saving the original: .. code-block:: python from django.db import models - from imagekit.models.fields import ProcessedImageField + from imagekit.models import ProcessedImageField class Photo(models.Model): - processed_image = ProcessedImageField(format='JPEG', options={'quality': 90}) + avatar_thumbnail = ProcessedImageField(spec_id='myapp:fancy_thumbnail', + upload_to='avatars') -See the class documentation for details. + photo = Photo.objects.all()[0] + print photo.avatar_thumbnail.url # > /static/avatars/MY-avatar_3.jpg + print photo.avatar_thumbnail.width # > 100 +Like with ``ImageSpecField``, the ``ProcessedImageField`` constructor also +has a shortcut version that allows you to inline spec definitions. -Processors ----------- -The real power of ImageKit comes from processors. Processors take an image, do -something to it, and return the result. By providing a list of processors to -your spec, you can expose different versions of the original image: +In Forms +^^^^^^^^ + +In addition to the model field above, there's also a form field version of the +``ProcessedImageField`` class. The functionality is basically the same (it +processes an image once and saves the result), but it's used in a form class: .. code-block:: python - from django.db import models - from imagekit.models import ImageSpecField - from imagekit.processors import ResizeToFill, Adjust + from django import forms + from imagekit.forms import ProcessedImageField - class Photo(models.Model): - original_image = models.ImageField(upload_to='photos') - thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1), - ResizeToFill(50, 50)], image_field='original_image', - format='JPEG', options={'quality': 90}) + class AvatarForm(forms.Form): + avatar_thumbnail = ProcessedImageField(spec_id='myapp:fancy_thumbnail') -The ``thumbnail`` property will now return a cropped image: +The benefit of using ``imagekit.forms.ProcessedImageField`` (as opposed to +``imagekit.models.ProcessedImageField`` above) is that it keeps the logic for +creating the image outside of your model (in which you would use a normal +Django ``ImageField``). You can even create multiple forms, each with their own +``ProcessedImageField``, that all store their results in the same image field. + +As with the model field classes, ``imagekit.forms.ProcessedImageField`` also +has a shortcut version that allows you to inline spec definitions. + + +Processors +---------- + +So far, we've only seen one processor: ``imagekit.processors.ResizeToFill``. But +ImageKit is capable of far more than just resizing images, and that power comes +from its processors. + +Processors take a PIL image object, do something to it, and return a new one. +A spec can make use of as many processors as you'd like, which will all be run +in order. .. code-block:: python - photo = Photo.objects.all()[0] - photo.thumbnail.url # > '/media/cache/photos/birthday_thumbnail.jpeg' - photo.thumbnail.width # > 50 - photo.original_image.width # > 1000 + from imagekit import ImageSpec + from imagekit.processors import TrimBorderColor, Adjust -The original image is not modified; ``thumbnail`` is a new file that is the -result of running the ``imagekit.processors.ResizeToFill`` processor on the -original. (If you only need to save the processed image, and not the original, -pass processors to a ``ProcessedImageField`` instead of an ``ImageSpecField``.) + class MySpec(ImageSpec): + processors = [ + TrimBorderColor(), + Adjust(contrast=1.2, sharpness=1.1), + ] + format = 'JPEG' + options = {'quality': 60} The ``imagekit.processors`` module contains processors for many common image manipulations, like resizing, rotating, and color adjustments. However, if they aren't up to the task, you can create your own. All you have to do is -implement a ``process()`` method: +define a class that implements a ``process()`` method: .. code-block:: python @@ -114,10 +232,23 @@ implement a ``process()`` method: # Code for adding the watermark goes here. return image - class Photo(models.Model): - original_image = models.ImageField(upload_to='photos') - watermarked_image = ImageSpecField([Watermark()], image_field='original_image', - format='JPEG', options={'quality': 90}) +That's all there is to it! To use your fancy new custom processor, just include +it in your spec's ``processors`` list: + +.. code-block:: python + + from imagekit import ImageSpec + from imagekit.processors import TrimBorderColor, Adjust + from myapp.processors import Watermark + + class MySpec(ImageSpec): + processors = [ + TrimBorderColor(), + Adjust(contrast=1.2, sharpness=1.1), + Watermark(), + ] + format = 'JPEG' + options = {'quality': 60} Admin @@ -134,12 +265,10 @@ Django admin classes: from imagekit.admin import AdminThumbnail from .models import Photo - class PhotoAdmin(admin.ModelAdmin): list_display = ('__str__', 'admin_thumbnail') admin_thumbnail = AdminThumbnail(image_field='thumbnail') - admin.site.register(Photo, PhotoAdmin) AdminThumbnail can even use a custom template. For more information, see @@ -148,40 +277,6 @@ AdminThumbnail can even use a custom template. For more information, see .. _`Django admin change list`: https://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-change-list -Image Cache Backends --------------------- - -Whenever you access properties like ``url``, ``width`` and ``height`` of an -``ImageSpecField``, its cached image is validated; whenever you save a new image -to the ``ImageField`` your spec uses as a source, the spec image is invalidated. -The default way to validate a cache image is to check to see if the file exists -and, if not, generate a new one; the default way to invalidate the cache is to -delete the image. This is a very simple and straightforward way to handle cache -validation, but it has its drawbacks—for example, checking to see if the image -exists means frequently hitting the storage backend. - -Because of this, ImageKit allows you to define custom image cache backends. To -be a valid image cache backend, a class must implement three methods: -``validate``, ``invalidate``, and ``clear`` (which is called when the image is -no longer needed in any form, i.e. the model is deleted). Each of these methods -must accept a file object, but the internals are up to you. For example, you -could store the state (valid, invalid) of the cache in a database to avoid -filesystem access. You can then specify your image cache backend on a per-field -basis: - -.. code-block:: python - - class Photo(models.Model): - ... - thumbnail = ImageSpecField(..., image_cache_backend=MyImageCacheBackend()) - -Or in your ``settings.py`` file if you want to use it as the default: - -.. code-block:: python - - IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND = 'path.to.MyImageCacheBackend' - - Community --------- @@ -199,7 +294,3 @@ even Django—to contribute either: ImageKit's processors are standalone classes that are completely separate from the more intimidating internals of Django's ORM. If you've written a processor that you think might be useful to other people, open a pull request so we can take a look! - -ImageKit's image cache backends are also fairly isolated from the ImageKit guts. -If you've fine-tuned one to work perfectly for a popular file storage backend, -let us take a look! Maybe other people could use it. From 2a33a2ad88ad2b636eb1fbd86ae672f93e6a6ab0 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Mon, 15 Oct 2012 21:17:58 -0400 Subject: [PATCH 042/527] Fix circular import utils > imagecache.backends --- imagekit/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 07f05e52..35671ac6 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -439,5 +439,8 @@ def __init__(self, spec): self.options = getattr(spec, 'options', None) self.autoconvert = getattr(spec, 'autoconvert', True) self.storage = getattr(spec, 'storage', None) - self.image_cache_backend = getattr(spec, 'image_cache_backend', None) \ - or get_default_image_cache_backend() + self.image_cache_backend = getattr(spec, 'image_cache_backend', None) + + if not self.image_cache_backend: + from .imagecache.backends import get_default_image_cache_backend + self.image_cache_backend = get_default_image_cache_backend() From c0b79a227d893c464cb37c2e9171f799111ee2a0 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Mon, 15 Oct 2012 23:53:05 -0400 Subject: [PATCH 043/527] Remove ImageSpecFieldFile in favor of ImageSpecFile --- imagekit/files.py | 23 +++--- imagekit/models/fields/files.py | 122 +------------------------------- imagekit/models/fields/utils.py | 25 ++++++- imagekit/utils.py | 6 ++ 4 files changed, 44 insertions(+), 132 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 0d9837fe..b3b543c7 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -15,6 +15,9 @@ def __init__(self, spec, source_file, spec_id): self.source_file = source_file self.spec_id = spec_id + def get_hash(self): + return self.spec.get_hash(self.source_file) + @property def url(http://github.com/self): self.validate() @@ -37,14 +40,18 @@ def validate(self): @property def name(self): - source_filename = self.source_file.name - filepath, basename = os.path.split(source_filename) - filename = os.path.splitext(basename)[0] - extension = suggest_extension(source_filename, self.spec.format) - new_name = '%s%s' % (filename, extension) - cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ - [filepath, new_name] - return os.path.join(*cache_filename) + name = self.spec.generate_filename(self.source_file) + if name is not None: + return name + else: + source_filename = self.source_file.name + filepath, basename = os.path.split(source_filename) + filename = os.path.splitext(basename)[0] + extension = suggest_extension(source_filename, self.spec.format) + new_name = '%s%s' % (filename, extension) + cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ + [filepath, new_name] + return os.path.join(*cache_filename) def generate(self, save=True): return self.spec.generate_file(self.name, self.source_file, save) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 691ce6b1..f0fc542f 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,124 +1,4 @@ -from django.db.models.fields.files import ImageField, ImageFieldFile - - -class ImageSpecFieldFile(ImageFieldFile): - def __init__(self, instance, field, attname): - super(ImageSpecFieldFile, self).__init__(instance, field, None) - self.attname = attname - - def get_hash(self): - return self.field.spec.get_hash(self.source_file) - - @property - def source_file(self): - field_name = getattr(self.field, 'image_field', None) - if field_name: - field_file = getattr(self.instance, field_name) - else: - image_fields = [getattr(self.instance, f.attname) for f in \ - self.instance.__class__._meta.fields if \ - isinstance(f, ImageField)] - if len(image_fields) == 0: - raise Exception('%s does not define any ImageFields, so your' \ - ' %s ImageSpecField has no image to act on.' % \ - (self.instance.__class__.__name__, self.attname)) - elif len(image_fields) > 1: - raise Exception('%s defines multiple ImageFields, but you' \ - ' have not specified an image_field for your %s' \ - ' ImageSpecField.' % (self.instance.__class__.__name__, - self.attname)) - else: - field_file = image_fields[0] - return field_file - - def _require_file(self): - if not self.source_file: - raise ValueError("The '%s' attribute's image_field has no file associated with it." % self.attname) - self.field.spec.image_cache_strategy.invoke_callback('access', self) - - def clear(self): - return self.field.spec.image_cache_backend.clear(self) - - def invalidate(self): - return self.field.spec.image_cache_backend.invalidate(self) - - def validate(self): - return self.field.spec.image_cache_backend.validate(self) - - def generate(self, save=True): - """ - Generates a new image file by processing the source file and returns - the content of the result, ready for saving. - - """ - return self.field.spec.generate_file(self.name, self.source_file, - save) - - def delete(self, save=False): - """ - Pulled almost verbatim from ``ImageFieldFile.delete()`` and - ``FieldFile.delete()`` but with the attempts to reset the instance - property removed. - - """ - # Clear the image dimensions cache - if hasattr(self, '_dimensions_cache'): - del self._dimensions_cache - - # Only close the file if it's already open, which we know by the - # presence of self._file. - if hasattr(self, '_file'): - self.close() - del self.file - - if self.name and self.storage.exists(self.name): - try: - self.storage.delete(self.name) - except NotImplementedError: - pass - - # Delete the filesize cache. - if hasattr(self, '_size'): - del self._size - self._committed = False - - if save: - self.instance.save() - - @property - def name(self): - """ - Specifies the filename that the cached image will use. - - """ - return self.field.spec.generate_filename(self.source_file) - - @name.setter - def name(self, value): - # TODO: Figure out a better way to handle this. We really don't want - # to allow anybody to set the name, but ``File.__init__`` (which is - # called by ``ImageSpecFieldFile.__init__``) does, so we have to allow - # it at least that one time. - pass - - @property - def storage(self): - return getattr(self, '_storage', None) or self.field.storage or self.source_file.storage - - @storage.setter - def storage(self, storage): - self._storage = storage - - def __getstate__(self): - return dict( - attname=self.attname, - instance=self.instance, - ) - - def __setstate__(self, state): - self.attname = state['attname'] - self.instance = state['instance'] - self.field = getattr(self.instance.__class__, self.attname) +from django.db.models.fields.files import ImageFieldFile class ProcessedImageFieldFile(ImageFieldFile): diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 3014b53e..dab61702 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,5 @@ -from .files import ImageSpecFieldFile +from ...files import ImageSpecFile +from django.db.models.fields.files import ImageField class ImageSpecFileDescriptor(object): @@ -10,8 +11,26 @@ def __get__(self, instance, owner): if instance is None: return self.field else: - img_spec_file = ImageSpecFieldFile(instance, self.field, - self.attname) + field_name = getattr(self.field, 'image_field', None) + if field_name: + source_file = getattr(instance, field_name) + else: + image_fields = [getattr(instance, f.attname) for f in \ + instance.__class__._meta.fields if \ + isinstance(f, ImageField)] + if len(image_fields) == 0: + raise Exception('%s does not define any ImageFields, so your' \ + ' %s ImageSpecField has no image to act on.' % \ + (instance.__class__.__name__, self.attname)) + elif len(image_fields) > 1: + raise Exception('%s defines multiple ImageFields, but you' \ + ' have not specified an image_field for your %s' \ + ' ImageSpecField.' % (instance.__class__.__name__, + self.attname)) + else: + source_file = image_fields[0] + img_spec_file = ImageSpecFile(self.field.spec, source_file, + self.attname) instance.__dict__[self.attname] = img_spec_file return img_spec_file diff --git a/imagekit/utils.py b/imagekit/utils.py index 35671ac6..d33d83d7 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -440,6 +440,12 @@ def __init__(self, spec): self.autoconvert = getattr(spec, 'autoconvert', True) self.storage = getattr(spec, 'storage', None) self.image_cache_backend = getattr(spec, 'image_cache_backend', None) + # TODO: get_hash default return value. + self.get_hash = getattr(spec, 'get_hash', lambda f: None) + # TODO: generate_filename default return value. + self.generate_filename = getattr(spec, 'generate_filename', lambda f: None) + # TODO: generate_file default return value. + self.generate_file = getattr(spec, 'generate_file', lambda f: None) if not self.image_cache_backend: from .imagecache.backends import get_default_image_cache_backend From 80b723b510ee5253e62cbac1b244a422c8e852de Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 21:31:47 -0400 Subject: [PATCH 044/527] Move IKContentFile to imagekit.files --- imagekit/files.py | 34 ++++++++++++++++++++++++++++++---- imagekit/specs/__init__.py | 6 +++--- imagekit/utils.py | 27 --------------------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index b3b543c7..98560fc2 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,8 +1,9 @@ -import os - +from django.core.files.base import ContentFile from django.db.models.fields.files import ImageFieldFile - -from .utils import SpecWrapper, suggest_extension +from django.utils.encoding import smart_str, smart_unicode +import os +from .utils import (SpecWrapper, suggest_extension, format_to_mimetype, + extension_to_mimetype) class ImageSpecFile(ImageFieldFile): @@ -55,3 +56,28 @@ def name(self): def generate(self, save=True): return self.spec.generate_file(self.name, self.source_file, save) + + +class IKContentFile(ContentFile): + """ + Wraps a ContentFile in a file-like object with a filename and a + content_type. A PIL image format can be optionally be provided as a content + type hint. + + """ + def __init__(self, filename, content, format=None): + self.file = ContentFile(content) + self.file.name = filename + mimetype = getattr(self.file, 'content_type', None) + if format and not mimetype: + mimetype = format_to_mimetype(format) + if not mimetype: + ext = os.path.splitext(filename or '')[1] + mimetype = extension_to_mimetype(ext) + self.file.content_type = mimetype + + def __str__(self): + return smart_str(self.file.name or '') + + def __unicode__(self): + return smart_unicode(self.file.name or u'') diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index d6271d77..5d712283 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,13 +4,13 @@ import pickle from .signals import source_created, source_changed, source_deleted from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered -from ..files import ImageSpecFile +from ..files import ImageSpecFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..lib import StringIO from ..processors import ProcessorPipeline -from ..utils import (open_image, extension_to_format, IKContentFile, - img_to_fobj, suggest_extension) +from ..utils import (open_image, extension_to_format, img_to_fobj, + suggest_extension) class SpecRegistry(object): diff --git a/imagekit/utils.py b/imagekit/utils.py index d33d83d7..cdd9b47e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -4,9 +4,7 @@ import types from django.core.exceptions import ImproperlyConfigured -from django.core.files.base import ContentFile from django.db.models.loading import cache -from django.utils.encoding import smart_str, smart_unicode from django.utils.functional import wraps from django.utils.importlib import import_module @@ -18,31 +16,6 @@ PALETTE_TRANSPARENCY_FORMATS = ['PNG', 'GIF'] -class IKContentFile(ContentFile): - """ - Wraps a ContentFile in a file-like object with a filename and a - content_type. A PIL image format can be optionally be provided as a content - type hint. - - """ - def __init__(self, filename, content, format=None): - self.file = ContentFile(content) - self.file.name = filename - mimetype = getattr(self.file, 'content_type', None) - if format and not mimetype: - mimetype = format_to_mimetype(format) - if not mimetype: - ext = os.path.splitext(filename or '')[1] - mimetype = extension_to_mimetype(ext) - self.file.content_type = mimetype - - def __str__(self): - return smart_str(self.file.name or '') - - def __unicode__(self): - return smart_unicode(self.file.name or u'') - - def img_to_fobj(img, format, autoconvert=True, **options): return save_image(img, StringIO(), format, options, autoconvert) From ca391fbf0ab019d3463a3a8a4c477da6f9e578f8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 21:36:40 -0400 Subject: [PATCH 045/527] Change cache prefix --- imagekit/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index d245b50b..e99cfcdd 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -6,7 +6,7 @@ class ImageKitConf(AppConf): DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.backends.Simple' CACHE_BACKEND = None CACHE_DIR = 'CACHE/images' - CACHE_PREFIX = 'ik-' + CACHE_PREFIX = 'imagekit:' DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' def configure_cache_backend(self, value): From 7f6e97a37a55ad0ff8a0e9210f8073a809d036fb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 21:46:23 -0400 Subject: [PATCH 046/527] Rename Pessimistic to JustInTime --- imagekit/conf.py | 2 +- imagekit/imagecache/strategies.py | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index e99cfcdd..d183f00d 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -7,7 +7,7 @@ class ImageKitConf(AppConf): CACHE_BACKEND = None CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'imagekit:' - DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.Pessimistic' + DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.JustInTime' def configure_cache_backend(self, value): if value is None: diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index e44929a4..f1346731 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -2,26 +2,21 @@ from ..utils import get_singleton -class Pessimistic(object): +class JustInTime(object): """ - A caching strategy that validates the file every time it's accessed. + A caching strategy that validates the file right before it's needed. """ def on_accessed(self, file): validate_now(file) - def on_source_deleted(self, file): - clear_now(file) - - def on_source_changed(self, file): - validate_now(file) - class Optimistic(object): """ - A caching strategy that validates when the source file changes and assumes - that the cached file will persist. + A caching strategy that acts immediately when the source file chages and + assumes that the cache files will not be removed (i.e. doesn't revalidate + on access). """ From 1452f04cdad6b931ee3fffd5ff5ab422ee76f2a7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:03:50 -0400 Subject: [PATCH 047/527] Remove unused parameter --- imagekit/models/fields/files.py | 3 +-- imagekit/specs/__init__.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index f0fc542f..6e5c489d 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -4,6 +4,5 @@ class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): new_filename = self.field.spec.generate_filename(self.instance, name) - img, content = self.field.spec.process_content(content, - new_filename, self) + img, content = self.field.spec.process_content(content, new_filename) return super(ProcessedImageFieldFile, self).save(name, content, save) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 5d712283..279af0ae 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -119,7 +119,7 @@ def generate_filename(self, source_file): return filename - def process_content(self, content, filename=None, source_file=None): + def process_content(self, content, filename=None): img = open_image(content) original_format = img.format @@ -214,7 +214,7 @@ def generate_file(self, filename, source_file, save=True): fp.seek(0) fp = StringIO(fp.read()) - img, content = self.process_content(fp, filename, source_file) + img, content = self.process_content(fp, filename) if save: storage = self.storage or source_file.storage From 8ef1437beabc75ec01f0c12c4e58a31916f47730 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:06:24 -0400 Subject: [PATCH 048/527] Remove apply() method --- imagekit/specs/__init__.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 279af0ae..a1f331b1 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -184,18 +184,9 @@ def __init__(self, processors=None, format=None, options=None, self.image_cache_backend = image_cache_backend or self.image_cache_backend or get_default_image_cache_backend() self.image_cache_strategy = StrategyWrapper(image_cache_strategy or self.image_cache_strategy) - # TODO: Can we come up with a better name for this? "process" may cause confusion with processors' process() - def apply(self, source_file): - """ - Creates a file object that represents the combination of a spec and - source file. - - """ - return ImageSpecFile(self, source_file) - # TODO: I don't like this interface. Is there a standard Python one? pubsub? def _handle_source_event(self, event_name, source_file): - file = self.apply(source_file) + file = ImageSpecFile(self, source_file) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) def generate_file(self, filename, source_file, save=True): From 37e0de30696aff3d0628bd3270e19244d9450556 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:10:52 -0400 Subject: [PATCH 049/527] Move signals module --- imagekit/{specs => }/signals.py | 0 imagekit/specs/__init__.py | 2 +- imagekit/specs/sources.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename imagekit/{specs => }/signals.py (100%) diff --git a/imagekit/specs/signals.py b/imagekit/signals.py similarity index 100% rename from imagekit/specs/signals.py rename to imagekit/signals.py diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index a1f331b1..5a63b732 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -2,13 +2,13 @@ from hashlib import md5 import os import pickle -from .signals import source_created, source_changed, source_deleted from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered from ..files import ImageSpecFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..lib import StringIO from ..processors import ProcessorPipeline +from ..signals import source_created, source_changed, source_deleted from ..utils import (open_image, extension_to_format, img_to_fobj, suggest_extension) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 42f8c85c..958fa61a 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -1,6 +1,6 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from .signals import source_created, source_changed, source_deleted +from ..signals import source_created, source_changed, source_deleted def ik_model_receiver(fn): From 3308c92a713e32d55bfce38c7e9671d7eb2422c9 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:23:14 -0400 Subject: [PATCH 050/527] Remove SpecWrapper class We don't need it now that we have an ImageSpec class --- imagekit/files.py | 5 +---- imagekit/utils.py | 25 ------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 98560fc2..e3c1b874 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,16 +2,13 @@ from django.db.models.fields.files import ImageFieldFile from django.utils.encoding import smart_str, smart_unicode import os -from .utils import (SpecWrapper, suggest_extension, format_to_mimetype, +from .utils import (suggest_extension, format_to_mimetype, extension_to_mimetype) class ImageSpecFile(ImageFieldFile): def __init__(self, spec, source_file, spec_id): - spec = SpecWrapper(spec) - self.storage = spec.storage or source_file.storage - self.spec = spec self.source_file = source_file self.spec_id = spec_id diff --git a/imagekit/utils.py b/imagekit/utils.py index cdd9b47e..1c76977a 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -398,28 +398,3 @@ def autodiscover(): # attempting to import it, otherwise we want it to bubble up. if module_has_submodule(mod, 'imagespecs'): raise - - -class SpecWrapper(object): - """ - Wraps a user-defined spec object so we can access properties that don't - exist without errors. - - """ - def __init__(self, spec): - self.processors = getattr(spec, 'processors', None) - self.format = getattr(spec, 'format', None) - self.options = getattr(spec, 'options', None) - self.autoconvert = getattr(spec, 'autoconvert', True) - self.storage = getattr(spec, 'storage', None) - self.image_cache_backend = getattr(spec, 'image_cache_backend', None) - # TODO: get_hash default return value. - self.get_hash = getattr(spec, 'get_hash', lambda f: None) - # TODO: generate_filename default return value. - self.generate_filename = getattr(spec, 'generate_filename', lambda f: None) - # TODO: generate_file default return value. - self.generate_file = getattr(spec, 'generate_file', lambda f: None) - - if not self.image_cache_backend: - from .imagecache.backends import get_default_image_cache_backend - self.image_cache_backend = get_default_image_cache_backend() From a4ef8aa681842b6513510712d9a042b2827bc714 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:30:36 -0400 Subject: [PATCH 051/527] Add before_access signal --- imagekit/files.py | 5 +++-- imagekit/imagecache/strategies.py | 9 ++++++++- imagekit/signals.py | 1 + imagekit/specs/__init__.py | 7 ++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index e3c1b874..a4433296 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,6 +2,7 @@ from django.db.models.fields.files import ImageFieldFile from django.utils.encoding import smart_str, smart_unicode import os +from .signals import before_access from .utils import (suggest_extension, format_to_mimetype, extension_to_mimetype) @@ -18,11 +19,11 @@ def get_hash(self): @property def url(http://github.com/self): - self.validate() + before_access.send(sender=self, spec=self.spec, file=self) return super(ImageFieldFile, self).url def _get_file(self): - self.validate() + before_access.send(sender=self, spec=self.spec, file=self) return super(ImageFieldFile, self).file file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index f1346731..3eca7473 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -8,7 +8,7 @@ class JustInTime(object): """ - def on_accessed(self, file): + def before_access(self, file): validate_now(file) @@ -50,3 +50,10 @@ def invoke_callback(self, name, *args, **kwargs): func = getattr(self._wrapped, name, None) if func: func(*args, **kwargs) + + def __unicode__(self): + return unicode(self._wrapped) + + + def __str__(self): + return str(self._wrapped) diff --git a/imagekit/signals.py b/imagekit/signals.py index 7c0888c2..4c7aefad 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,5 +1,6 @@ from django.dispatch import Signal +before_access = Signal() source_created = Signal(providing_args=[]) source_changed = Signal() source_deleted = Signal() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 5a63b732..41f95c57 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -8,7 +8,8 @@ from ..imagecache.strategies import StrategyWrapper from ..lib import StringIO from ..processors import ProcessorPipeline -from ..signals import source_created, source_changed, source_deleted +from ..signals import (before_access, source_created, source_changed, + source_deleted) from ..utils import (open_image, extension_to_format, img_to_fobj, suggest_extension) @@ -35,6 +36,7 @@ def __init__(self): self._sources = {} for signal in self._source_signals: signal.connect(self.source_receiver) + before_access.connect(self.before_access_receiver) def register(self, id, spec): if id in self._specs: @@ -66,6 +68,9 @@ def add_source(self, source, spec_id): self._sources[source] = set() self._sources[source].add(spec_id) + def before_access_receiver(self, sender, spec, file, **kwargs): + spec.image_cache_strategy.invoke_callback('before_access', file) + def source_receiver(self, sender, source_file, signal, info, **kwargs): """ Redirects signals dispatched on sources to the appropriate specs. From 13b59ef85e28901aad5a78b6b185511fc3b7a3c4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:33:17 -0400 Subject: [PATCH 052/527] Reorder methods --- imagekit/files.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index a4433296..0079f36d 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -28,15 +28,6 @@ def _get_file(self): file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file) - def clear(self): - return self.spec.image_cache_backend.clear(self) - - def invalidate(self): - return self.spec.image_cache_backend.invalidate(self) - - def validate(self): - return self.spec.image_cache_backend.validate(self) - @property def name(self): name = self.spec.generate_filename(self.source_file) @@ -52,6 +43,15 @@ def name(self): [filepath, new_name] return os.path.join(*cache_filename) + def clear(self): + return self.spec.image_cache_backend.clear(self) + + def invalidate(self): + return self.spec.image_cache_backend.invalidate(self) + + def validate(self): + return self.spec.image_cache_backend.validate(self) + def generate(self, save=True): return self.spec.generate_file(self.name, self.source_file, save) From fdc08aeeb0fb466d38c78c11661fa909c4491980 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:52:01 -0400 Subject: [PATCH 053/527] Don't extend ImageFieldFile This file isn't just for fields anymore, so we want to get rid of all the ORM stuff. --- imagekit/files.py | 79 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 0079f36d..34996438 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,5 +1,5 @@ -from django.core.files.base import ContentFile -from django.db.models.fields.files import ImageFieldFile +from django.core.files.base import ContentFile, File +from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode import os from .signals import before_access @@ -7,7 +7,69 @@ extension_to_mimetype) -class ImageSpecFile(ImageFieldFile): +class BaseImageSpecFile(File): + """ + This class contains all of the methods we need from + django.db.models.fields.files.FieldFile, but with the model stuff ripped + out. It's only extended by one class, but we keep it separate for + organizational reasons. + + """ + + def __init__(self): + pass + + def _require_file(self): + if not self: + raise ValueError() + + def _get_file(self): + self._require_file() + if not hasattr(self, '_file') or self._file is None: + self._file = self.storage.open(self.name, 'rb') + return self._file + + def _set_file(self, file): + self._file = file + + def _del_file(self): + del self._file + + file = property(_get_file, _set_file, _del_file) + + def _get_path(self): + self._require_file() + return self.storage.path(self.name) + path = property(_get_path) + + def _get_url(http://github.com/self): + self._require_file() + return self.storage.url(http://github.com/self.name) + url = property(_get_url) + + def _get_size(self): + self._require_file() + if not self._committed: + return self.file.size + return self.storage.size(self.name) + size = property(_get_size) + + def open(self, mode='rb'): + self._require_file() + self.file.open(mode) + + def _get_closed(self): + file = getattr(self, '_file', None) + return file is None or file.closed + closed = property(_get_closed) + + def close(self): + file = getattr(self, '_file', None) + if file is not None: + file.close() + + +class ImageSpecFile(ImageFile, BaseImageSpecFile): def __init__(self, spec, source_file, spec_id): self.storage = spec.storage or source_file.storage self.spec = spec @@ -17,16 +79,9 @@ def __init__(self, spec, source_file, spec_id): def get_hash(self): return self.spec.get_hash(self.source_file) - @property - def url(http://github.com/self): + def _require_file(self): before_access.send(sender=self, spec=self.spec, file=self) - return super(ImageFieldFile, self).url - - def _get_file(self): - before_access.send(sender=self, spec=self.spec, file=self) - return super(ImageFieldFile, self).file - - file = property(_get_file, ImageFieldFile._set_file, ImageFieldFile._del_file) + return super(ImageSpecFile, self)._require_file() @property def name(self): From 5ca8b7f4ba990387bab58c36c4fe5e8fec2aa923 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 22:59:40 -0400 Subject: [PATCH 054/527] Rename process_file; don't return image object This function will just be used to apply the spec and create a new file; useful for transforming images in views, etc. --- imagekit/models/fields/files.py | 2 +- imagekit/specs/__init__.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 6e5c489d..f7f887ac 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -4,5 +4,5 @@ class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): new_filename = self.field.spec.generate_filename(self.instance, name) - img, content = self.field.spec.process_content(content, new_filename) + content = self.field.spec.apply(content, new_filename) return super(ProcessedImageFieldFile, self).save(name, content, save) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 41f95c57..e1662180 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -124,7 +124,7 @@ def generate_filename(self, source_file): return filename - def process_content(self, content, filename=None): + def apply(self, content, filename=None): img = open_image(content) original_format = img.format @@ -148,7 +148,7 @@ def process_content(self, content, filename=None): imgfile = img_to_fobj(img, format, **options) content = IKContentFile(filename, imgfile.read(), format=format) - return img, content + return content class ImageSpec(BaseImageSpec): @@ -210,7 +210,7 @@ def generate_file(self, filename, source_file, save=True): fp.seek(0) fp = StringIO(fp.read()) - img, content = self.process_content(fp, filename) + content = self.apply(fp, filename) if save: storage = self.storage or source_file.storage From 738bbfa9a19ac286f985fba4ab2e06ed2f1ee397 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:38:44 -0400 Subject: [PATCH 055/527] Move cache file naming into ImageSpecFile --- imagekit/files.py | 27 +++++++++++----------- imagekit/models/fields/__init__.py | 37 +++++++++++++++--------------- imagekit/models/fields/files.py | 10 +++++--- imagekit/models/fields/utils.py | 3 +-- imagekit/specs/__init__.py | 13 ----------- 5 files changed, 40 insertions(+), 50 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 34996438..8b417c44 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode @@ -70,11 +71,10 @@ def close(self): class ImageSpecFile(ImageFile, BaseImageSpecFile): - def __init__(self, spec, source_file, spec_id): + def __init__(self, spec, source_file): self.storage = spec.storage or source_file.storage self.spec = spec self.source_file = source_file - self.spec_id = spec_id def get_hash(self): return self.spec.get_hash(self.source_file) @@ -85,18 +85,17 @@ def _require_file(self): @property def name(self): - name = self.spec.generate_filename(self.source_file) - if name is not None: - return name - else: - source_filename = self.source_file.name - filepath, basename = os.path.split(source_filename) - filename = os.path.splitext(basename)[0] - extension = suggest_extension(source_filename, self.spec.format) - new_name = '%s%s' % (filename, extension) - cache_filename = ['cache', 'iktt'] + self.spec_id.split(':') + \ - [filepath, new_name] - return os.path.join(*cache_filename) + source_filename = self.source_file.name + filename = None + if source_filename: + hash = self.spec.get_hash(self.source_file) + ext = suggest_extension(source_filename, self.spec.format) + filename = os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (hash, ext))) + + return filename def clear(self): return self.spec.image_cache_backend.clear(self) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 148212c9..ecc6bbee 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -9,7 +9,20 @@ from ...specs.sources import ImageFieldSpecSource -class ImageSpecField(SpecHost): +class SpecHostField(SpecHost): + def set_spec_id(self, cls, name): + # Generate a spec_id to register the spec with. The default spec id is + # ":_" + if not getattr(self, 'spec_id', None): + spec_id = (u'%s:%s_%s' % (cls._meta.app_label, + cls._meta.object_name, name)).lower() + + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + super(SpecHostField, self).set_spec_id(spec_id) + + +class ImageSpecField(SpecHostField): """ The heart and soul of the ImageKit library, ImageSpecField allows you to add variants of uploaded images to your models. @@ -34,23 +47,14 @@ def storage(self): def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) - - # Generate a spec_id to register the spec with. The default spec id is - # ":_" - if not getattr(self, 'spec_id', None): - self.spec_id = (u'%s:%s_%s' % (cls._meta.app_label, - cls._meta.object_name, name)).lower() - - # Register the spec with the id. This allows specs to be overridden - # later, from outside of the model definition. - self.set_spec_id(self.spec_id) + self.set_spec_id(cls, name) # Add the model and field as a source for this spec id specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field), self.spec_id) -class ProcessedImageField(models.ImageField, SpecHost): +class ProcessedImageField(models.ImageField, SpecHostField): """ ProcessedImageField is an ImageField that runs processors on the uploaded image *before* saving it to storage. This is in contrast to specs, which @@ -76,12 +80,9 @@ def __init__(self, processors=None, format=None, options=None, models.ImageField.__init__(self, verbose_name, name, width_field, height_field, **kwargs) - def get_filename(self, filename): - filename = os.path.normpath(self.storage.get_valid_name( - os.path.basename(filename))) - name, ext = os.path.splitext(filename) - ext = suggest_extension(filename, self.spec.format) - return u'%s%s' % (name, ext) + def contribute_to_class(self, cls, name): + self.set_spec_id(cls, name) + return super(ProcessedImageField, self).contribute_to_class(cls, name) try: diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index f7f887ac..3c9ffd68 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,8 +1,12 @@ from django.db.models.fields.files import ImageFieldFile +import os +from ...utils import suggest_extension class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): - new_filename = self.field.spec.generate_filename(self.instance, name) - content = self.field.spec.apply(content, new_filename) - return super(ProcessedImageFieldFile, self).save(name, content, save) + filename, ext = os.path.splitext(name) + ext = suggest_extension(name, self.field.spec.format) + new_name = '%s%s' % (filename, ext) + content = self.field.spec.apply(content, new_name) + return super(ProcessedImageFieldFile, self).save(new_name, content, save) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index dab61702..ce55a187 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -29,8 +29,7 @@ def __get__(self, instance, owner): self.attname)) else: source_file = image_fields[0] - img_spec_file = ImageSpecFile(self.field.spec, source_file, - self.attname) + img_spec_file = ImageSpecFile(self.field.spec, source_file) instance.__dict__[self.attname] = img_spec_file return img_spec_file diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e1662180..883b4e04 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -111,19 +111,6 @@ def get_hash(self, source_file): str(self.autoconvert), ]).encode('utf-8')).hexdigest() - def generate_filename(self, source_file): - source_filename = source_file.name - filename = None - if source_filename: - hash = self.get_hash(source_file) - extension = suggest_extension(source_filename, self.format) - filename = os.path.normpath(os.path.join( - settings.IMAGEKIT_CACHE_DIR, - os.path.splitext(source_filename)[0], - '%s%s' % (hash, extension))) - - return filename - def apply(self, content, filename=None): img = open_image(content) original_format = img.format From df8905f7e4ae2ec2d7e2032de9112c0576fe2ef2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:39:10 -0400 Subject: [PATCH 056/527] Remove unused imports --- imagekit/models/fields/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index ecc6bbee..0cb6443f 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,10 +1,7 @@ -import os - from django.db import models from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor from ... import specs -from ...utils import suggest_extension from ...specs import SpecHost from ...specs.sources import ImageFieldSpecSource From 5c6d1aef5dcd48ae5ada88d685372673e8092657 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:51:26 -0400 Subject: [PATCH 057/527] Rename ImageSpecFile You can generate other "spec" files (using apply will get you one). This one is for saving cache files and its name should reflect that. --- imagekit/files.py | 6 +++--- imagekit/models/fields/utils.py | 8 ++++---- imagekit/specs/__init__.py | 4 ++-- imagekit/templatetags/imagekit_tags.py | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 8b417c44..df4055e4 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -8,7 +8,7 @@ extension_to_mimetype) -class BaseImageSpecFile(File): +class BaseIKFile(File): """ This class contains all of the methods we need from django.db.models.fields.files.FieldFile, but with the model stuff ripped @@ -70,7 +70,7 @@ def close(self): file.close() -class ImageSpecFile(ImageFile, BaseImageSpecFile): +class ImageSpecCacheFile(ImageFile, BaseIKFile): def __init__(self, spec, source_file): self.storage = spec.storage or source_file.storage self.spec = spec @@ -81,7 +81,7 @@ def get_hash(self): def _require_file(self): before_access.send(sender=self, spec=self.spec, file=self) - return super(ImageSpecFile, self)._require_file() + return super(ImageSpecCacheFile, self)._require_file() @property def name(self): diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index ce55a187..9490966f 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...files import ImageSpecFile +from ...files import ImageSpecCacheFile from django.db.models.fields.files import ImageField @@ -29,9 +29,9 @@ def __get__(self, instance, owner): self.attname)) else: source_file = image_fields[0] - img_spec_file = ImageSpecFile(self.field.spec, source_file) - instance.__dict__[self.attname] = img_spec_file - return img_spec_file + file = ImageSpecCacheFile(self.field.spec, source_file) + instance.__dict__[self.attname] = file + return file def __set__(self, instance, value): instance.__dict__[self.attname] = value diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 883b4e04..faf5594d 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -3,7 +3,7 @@ import os import pickle from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered -from ..files import ImageSpecFile, IKContentFile +from ..files import ImageSpecCacheFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..lib import StringIO @@ -178,7 +178,7 @@ def __init__(self, processors=None, format=None, options=None, # TODO: I don't like this interface. Is there a standard Python one? pubsub? def _handle_source_event(self, event_name, source_file): - file = ImageSpecFile(self, source_file) + file = ImageSpecCacheFile(self, source_file) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) def generate_file(self, filename, source_file, save=True): diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 938a53bf..13230b49 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,6 +1,6 @@ from django import template from django.utils.safestring import mark_safe -from ..files import ImageSpecFile +from ..files import ImageSpecCacheFile from ..specs import spec_registry @@ -32,13 +32,13 @@ def render(self, context): spec = spec_registry.get_spec(spec_id) if callable(spec): spec = spec() - spec_file = ImageSpecFileHtmlWrapper(ImageSpecFile(spec, source_image, spec_id)) + file = ImageSpecFileHtmlWrapper(ImageSpecCacheFile(spec, source_image, spec_id)) if self.variable_name is not None: variable_name = str(self.variable_name) - context[variable_name] = spec_file + context[variable_name] = file return '' - return spec_file + return file #@register.tag From 9b81acd10c96c4c0aeadfb9275f5cc3a4ae24576 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:52:28 -0400 Subject: [PATCH 058/527] Don't pass removed argument --- imagekit/templatetags/imagekit_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 13230b49..82055d60 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -32,7 +32,7 @@ def render(self, context): spec = spec_registry.get_spec(spec_id) if callable(spec): spec = spec() - file = ImageSpecFileHtmlWrapper(ImageSpecCacheFile(spec, source_image, spec_id)) + file = ImageSpecFileHtmlWrapper(ImageSpecCacheFile(spec, source_image)) if self.variable_name is not None: variable_name = str(self.variable_name) context[variable_name] = file From a93832626a90471ab6c9efb44d461b355dce029c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:54:53 -0400 Subject: [PATCH 059/527] Return string from render method ...instead of wrapping the file with an object that has a __unicode__ method. If you want the actual file, you should use the assignment form. --- imagekit/templatetags/imagekit_tags.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 82055d60..9468a76e 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -7,17 +7,6 @@ register = template.Library() -class ImageSpecFileHtmlWrapper(object): - def __init__(self, image_spec_file): - self._image_spec_file = image_spec_file - - def __getattr__(self, name): - return getattr(self._image_spec_file, name) - - def __unicode__(self): - return mark_safe(u'' % self.url) - - class SpecNode(template.Node): def __init__(self, spec_id, source_image, variable_name=None): self.spec_id = spec_id @@ -32,13 +21,13 @@ def render(self, context): spec = spec_registry.get_spec(spec_id) if callable(spec): spec = spec() - file = ImageSpecFileHtmlWrapper(ImageSpecCacheFile(spec, source_image)) + file = ImageSpecCacheFile(spec, source_image) if self.variable_name is not None: variable_name = str(self.variable_name) context[variable_name] = file return '' - return file + return mark_safe(u'' % file.url) #@register.tag From 63ad9e442191ebff7ebb40d607a78fb0f9a181a4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Oct 2012 23:59:13 -0400 Subject: [PATCH 060/527] Remove registration methods from template tag The registry isn't just for template tags anymore. --- imagekit/specs/__init__.py | 13 +++++++++++++ imagekit/templatetags/imagekit_tags.py | 17 ----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index faf5594d..f43c04bc 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -265,3 +265,16 @@ def spec(self): registry = SpecRegistry() + + +def register(id, spec=None): + if not spec: + def decorator(cls): + registry.register(id, cls) + return cls + return decorator + registry.register(id, spec) + + +def unregister(id, spec): + registry.unregister(id, spec) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 9468a76e..2930d7b9 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -69,20 +69,3 @@ def spec(parser, token): spec = spec_tag = register.tag(spec) - - -def _register_spec(id, spec=None): - if not spec: - def decorator(cls): - spec_registry.register(id, cls) - return cls - return decorator - spec_registry.register(id, spec) - - -def _unregister_spec(id, spec): - spec_registry.unregister(id, spec) - - -spec_tag.register = _register_spec -spec_tag.unregister = _unregister_spec From 4c4727fa9fb4d61752b64dbd5627a190048d481c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:00:12 -0400 Subject: [PATCH 061/527] Remove unused import --- imagekit/specs/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index f43c04bc..2a1b1caf 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -10,8 +10,7 @@ from ..processors import ProcessorPipeline from ..signals import (before_access, source_created, source_changed, source_deleted) -from ..utils import (open_image, extension_to_format, img_to_fobj, - suggest_extension) +from ..utils import open_image, extension_to_format, img_to_fobj class SpecRegistry(object): From 77b33f757cfe955f1c8948869025f43d4fe9302a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:00:53 -0400 Subject: [PATCH 062/527] Correct example --- imagekit/templatetags/imagekit_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 2930d7b9..c365c2fa 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -38,7 +38,7 @@ def spec(parser, token): By default:: - {% spec 'myapp:thumbnail', mymodel.profile_image %} + {% spec 'myapp:thumbnail' mymodel.profile_image %} Generates an ````:: From 97d47c9c6cb781d9961b29fb35e62a31c2b852d2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:21:47 -0400 Subject: [PATCH 063/527] Remove generate_file. apply() does it all! There was a lot of garbage in that method and I don't know why. --- imagekit/files.py | 5 ++++- imagekit/specs/__init__.py | 24 ------------------------ 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index df4055e4..a52c8bf0 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -107,7 +107,10 @@ def validate(self): return self.spec.image_cache_backend.validate(self) def generate(self, save=True): - return self.spec.generate_file(self.name, self.source_file, save) + if self.source_file: # TODO: Should we error here or something if the source_file doesn't exist? + # Process the original image file. + content = self.spec.apply(self.source_file) + return self.storage.save(self.name, content) class IKContentFile(ContentFile): diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 2a1b1caf..aa1126cd 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -180,30 +180,6 @@ def _handle_source_event(self, event_name, source_file): file = ImageSpecCacheFile(self, source_file) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) - def generate_file(self, filename, source_file, save=True): - """ - Generates a new image file by processing the source file and returns - the content of the result, ready for saving. - - """ - if source_file: # TODO: Should we error here or something if the source_file doesn't exist? - # Process the original image file. - - try: - fp = source_file.storage.open(source_file.name) - except IOError: - return - fp.seek(0) - fp = StringIO(fp.read()) - - content = self.apply(fp, filename) - - if save: - storage = self.storage or source_file.storage - storage.save(filename, content) - - return content - class SpecHost(object): """ From a08edaca563833e367aaa2fc792983a5009c080b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:29:51 -0400 Subject: [PATCH 064/527] Handle storage in BaseIKFile --- imagekit/files.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index a52c8bf0..66680e04 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -17,8 +17,8 @@ class BaseIKFile(File): """ - def __init__(self): - pass + def __init__(self, storage): + self.storage = storage def _require_file(self): if not self: @@ -70,9 +70,10 @@ def close(self): file.close() -class ImageSpecCacheFile(ImageFile, BaseIKFile): +class ImageSpecCacheFile(BaseIKFile, ImageFile): def __init__(self, spec, source_file): - self.storage = spec.storage or source_file.storage + storage = spec.storage or source_file.storage + super(ImageSpecCacheFile, self).__init__(storage=storage) self.spec = spec self.source_file = source_file From 41fa1972129c104ed16e28612ceee55e0a0bdfd0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:31:38 -0400 Subject: [PATCH 065/527] Remove save kwarg--that's what generate() does! --- imagekit/files.py | 2 +- imagekit/imagecache/backends.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 66680e04..c7af4bba 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -107,7 +107,7 @@ def invalidate(self): def validate(self): return self.spec.image_cache_backend.validate(self) - def generate(self, save=True): + def generate(self): if self.source_file: # TODO: Should we error here or something if the source_file doesn't exist? # Process the original image file. content = self.spec.apply(self.source_file) diff --git a/imagekit/imagecache/backends.py b/imagekit/imagecache/backends.py index c7339ab6..922b1f47 100644 --- a/imagekit/imagecache/backends.py +++ b/imagekit/imagecache/backends.py @@ -67,7 +67,7 @@ def _validate(self, file): Generates a new image by running the processors on the source file. """ - file.generate(save=True) + file.generate() def invalidate(self, file): """ From ca324b7f529714f7c07779ae31fff92bba5f78c1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:32:31 -0400 Subject: [PATCH 066/527] Remove unused import --- imagekit/specs/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index aa1126cd..7aa8728a 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -6,7 +6,6 @@ from ..files import ImageSpecCacheFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper -from ..lib import StringIO from ..processors import ProcessorPipeline from ..signals import (before_access, source_created, source_changed, source_deleted) From 806ebd75b63ae20e526d9fb0f44d9e05dd688768 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 00:37:02 -0400 Subject: [PATCH 067/527] Don't return file from generate() The file is `self` --- imagekit/files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/files.py b/imagekit/files.py index c7af4bba..81db5796 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -111,7 +111,7 @@ def generate(self): if self.source_file: # TODO: Should we error here or something if the source_file doesn't exist? # Process the original image file. content = self.spec.apply(self.source_file) - return self.storage.save(self.name, content) + self.storage.save(self.name, content) class IKContentFile(ContentFile): From d8ce11e86e9d4fc01a667293d21a0d73f74545ca Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 01:11:05 -0400 Subject: [PATCH 068/527] Log warning when filename doesn't match expected value --- imagekit/files.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/imagekit/files.py b/imagekit/files.py index 81db5796..1f590f17 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,6 +2,7 @@ from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode +import logging import os from .signals import before_access from .utils import (suggest_extension, format_to_mimetype, @@ -111,7 +112,18 @@ def generate(self): if self.source_file: # TODO: Should we error here or something if the source_file doesn't exist? # Process the original image file. content = self.spec.apply(self.source_file) - self.storage.save(self.name, content) + actual_name = self.storage.save(self.name, content) + + if actual_name != self.name: + # TODO: Use named logger? + logging.warning('The storage backend %s did not save the file' + ' with the requested name ("%s") and instead used' + ' "%s". This may be because a file already existed with' + ' the requested name. If so, you may have meant to call' + ' validate() instead of generate(), or there may be a' + ' race condition in the image cache backend %s. The' + ' saved file will not be used.' % (self.storage, + self.name, actual_name, self.spec.image_cache_backend)) class IKContentFile(ContentFile): From a265fd79e1c250d7e6a8215b06aff8732b1cfc19 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 11:00:59 -0400 Subject: [PATCH 069/527] Correct example image URLs Generated files are stored in the media folder, not static --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 9b38119c..a616d754 100644 --- a/README.rst +++ b/README.rst @@ -94,7 +94,7 @@ Output: .. code-block:: html - A picture of me + A picture of me Not generating HTML image tags? No problem. The tag also functions as an assignment tag, providing access to the underlying file object: @@ -123,7 +123,7 @@ of applying a spec to another one of your model's fields: avatar_thumbnail = ImageSpecField(id='myapp:fancy_thumbnail', image_field='avatar') photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /static/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg + print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg print photo.avatar_thumbnail.width # > 100 Since defining a spec, registering it, and using it in a single model field is @@ -144,7 +144,7 @@ writing a subclass of ``ImageSpec``: image_field='avatar') photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /static/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg + print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg print photo.avatar_thumbnail.width # > 100 This has the exact same behavior as before, but the spec definition is inlined. @@ -164,7 +164,7 @@ a user-provided image without saving the original: upload_to='avatars') photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /static/avatars/MY-avatar_3.jpg + print photo.avatar_thumbnail.url # > /media/avatars/MY-avatar_3.jpg print photo.avatar_thumbnail.width # > 100 Like with ``ImageSpecField``, the ``ProcessedImageField`` constructor also From ca1db05c4e600cce5d2b6f615b548c5fb2116279 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 21:00:32 -0400 Subject: [PATCH 070/527] Use named logger --- imagekit/files.py | 6 ++---- imagekit/utils.py | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 1f590f17..12852cc8 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,11 +2,10 @@ from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode -import logging import os from .signals import before_access from .utils import (suggest_extension, format_to_mimetype, - extension_to_mimetype) + extension_to_mimetype, get_logger) class BaseIKFile(File): @@ -115,8 +114,7 @@ def generate(self): actual_name = self.storage.save(self.name, content) if actual_name != self.name: - # TODO: Use named logger? - logging.warning('The storage backend %s did not save the file' + get_logger().warning('The storage backend %s did not save the file' ' with the requested name ("%s") and instead used' ' "%s". This may be because a file already existed with' ' the requested name. If so, you may have meant to call' diff --git a/imagekit/utils.py b/imagekit/utils.py index 1c76977a..282b739a 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,3 +1,4 @@ +import logging import os import mimetypes import sys @@ -398,3 +399,10 @@ def autodiscover(): # attempting to import it, otherwise we want it to bubble up. if module_has_submodule(mod, 'imagespecs'): raise + + +def get_logger(logger_name='imagekit', add_null_handler=True): + logger = logging.getLogger(logger_name) + if add_null_handler: + logger.addHandler(logging.NullHandler()) + return logger From 98a6fff62dc9a4691770bf3b1d1729b600ff7d02 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 21:09:04 -0400 Subject: [PATCH 071/527] Add DEFAULT_FILE_STORAGE Setting; Closes #153 --- imagekit/conf.py | 1 + imagekit/files.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index d183f00d..ed568db1 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -8,6 +8,7 @@ class ImageKitConf(AppConf): CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'imagekit:' DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.JustInTime' + DEFAULT_FILE_STORAGE = None # Indicates that the source storage should be used def configure_cache_backend(self, value): if value is None: diff --git a/imagekit/files.py b/imagekit/files.py index 12852cc8..e04198d9 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -5,7 +5,7 @@ import os from .signals import before_access from .utils import (suggest_extension, format_to_mimetype, - extension_to_mimetype, get_logger) + extension_to_mimetype, get_logger, get_singleton) class BaseIKFile(File): @@ -72,7 +72,9 @@ def close(self): class ImageSpecCacheFile(BaseIKFile, ImageFile): def __init__(self, spec, source_file): - storage = spec.storage or source_file.storage + storage = (spec.storage or + get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') if settings.IMAGEKIT_DEFAULT_FILE_STORAGE + else source_file.storage) super(ImageSpecCacheFile, self).__init__(storage=storage) self.spec = spec self.source_file = source_file From 4f52e401d2b68316b6a29175251ce26a3391b0b1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 21:24:57 -0400 Subject: [PATCH 072/527] Handle null format --- imagekit/specs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 7aa8728a..ccb4cb47 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -104,7 +104,7 @@ def get_hash(self, source_file): return md5(''.join([ source_file.name, pickle.dumps(self.processors), - self.format, + str(self.format), pickle.dumps(self.options), str(self.autoconvert), ]).encode('utf-8')).hexdigest() From e300ce36a442de833c670af9c056766202fd4a2b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 21:25:19 -0400 Subject: [PATCH 073/527] Use new registry name --- imagekit/templatetags/imagekit_tags.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index c365c2fa..1d4cf82c 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,7 +1,7 @@ from django import template from django.utils.safestring import mark_safe from ..files import ImageSpecCacheFile -from ..specs import spec_registry +from .. import specs register = template.Library() @@ -18,7 +18,7 @@ def render(self, context): autodiscover() source_image = self.source_image.resolve(context) spec_id = self.spec_id.resolve(context) - spec = spec_registry.get_spec(spec_id) + spec = specs.registry.get_spec(spec_id) if callable(spec): spec = spec() file = ImageSpecCacheFile(spec, source_image) From 770a8cebf4682dc83442671fdeafc441aae8ea26 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 21:35:19 -0400 Subject: [PATCH 074/527] Fix iteration error --- imagekit/specs/sources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 958fa61a..15c852e6 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -73,7 +73,7 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): - for attname, file in self.get_field_dict(instance): + for attname, file in self.get_field_dict(instance).items(): self.dispatch_signal(source_deleted, file, sender, instance, attname) @ik_model_receiver From b0b466618f669f87ecfe66b9dd655415ba88ed83 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Oct 2012 23:39:48 -0400 Subject: [PATCH 075/527] Separate two forms of tag; support additional html attrs Closes #154 --- imagekit/templatetags/imagekit_tags.py | 115 +++++++++++++++++++------ 1 file changed, 90 insertions(+), 25 deletions(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 1d4cf82c..b092ca4f 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -1,5 +1,6 @@ from django import template from django.utils.safestring import mark_safe +import re from ..files import ImageSpecCacheFile from .. import specs @@ -7,27 +8,86 @@ register = template.Library() -class SpecNode(template.Node): - def __init__(self, spec_id, source_image, variable_name=None): - self.spec_id = spec_id - self.source_image = source_image - self.variable_name = variable_name +html_attr_pattern = r""" + (?P\w+) # The attribute name + ( + \s*=\s* # an equals sign, that may or may not have spaces around it + (?P + ("[^"]*") # a double-quoted value + | # or + ('[^']*') # a single-quoted value + | # or + ([^"'<>=\s]+) # an unquoted value + ) + )? +""" - def render(self, context): +html_attr_re = re.compile(html_attr_pattern, re.VERBOSE) + + +class SpecResultNodeMixin(object): + def __init__(self, spec_id, source_file): + self._spec_id = spec_id + self._source_file = source_file + + def get_spec(self, context): from ..utils import autodiscover autodiscover() - source_image = self.source_image.resolve(context) - spec_id = self.spec_id.resolve(context) + spec_id = self._spec_id.resolve(context) spec = specs.registry.get_spec(spec_id) if callable(spec): spec = spec() - file = ImageSpecCacheFile(spec, source_image) - if self.variable_name is not None: - variable_name = str(self.variable_name) - context[variable_name] = file - return '' + return spec + + def get_source_file(self, context): + return self._source_file.resolve(context) + + def get_file(self, context): + spec = self.get_spec(context) + source_file = self.get_source_file(context) + return ImageSpecCacheFile(spec, source_file) + + +class SpecResultAssignmentNode(template.Node, SpecResultNodeMixin): + def __init__(self, spec_id, source_file, variable_name): + super(SpecResultAssignmentNode, self).__init__(spec_id, source_file) + self._variable_name = variable_name + + def get_variable_name(self, context): + return unicode(self._variable_name) - return mark_safe(u'' % file.url) + def render(self, context): + variable_name = self.get_variable_name(context) + context[variable_name] = self.get_file(context) + return '' + + +class SpecResultImgTagNode(template.Node, SpecResultNodeMixin): + def __init__(self, spec_id, source_file, html_attrs): + super(SpecResultImgTagNode, self).__init__(spec_id, source_file) + self._html_attrs = html_attrs + + def get_html_attrs(self, context): + attrs = [] + for attr in self._html_attrs: + match = html_attr_re.search(attr) + if match: + attrs.append((match.group('name'), match.group('value'))) + return attrs + + def get_attr_str(self, k, v): + return k if v is None else '%s=%s' % (k, v) + + def render(self, context): + file = self.get_file(context) + attrs = self.get_html_attrs(context) + attr_dict = dict(attrs) + if not 'width' in attr_dict and not 'height' in attr_dict: + attrs = attrs + [('width', '"%s"' % file.width), + ('height', '"%s"' % file.height)] + attrs = [('src', '"%s"' % file.url)] + attrs + attr_str = ' '.join(self.get_attr_str(k, v) for k, v in attrs) + return mark_safe(u'' % attr_str) #@register.tag @@ -51,21 +111,26 @@ def spec(parser, token): """ - args = token.split_contents() - arg_count = len(args) - - if (arg_count < 3 or arg_count > 5 - or (arg_count > 3 and arg_count < 5) - or (args == 5 and args[3] != 'as')): + bits = token.split_contents() + tag_name = bits.pop(0) + + if len(bits) == 4 and bits[2] == 'as': + return SpecResultAssignmentNode( + parser.compile_filter(bits[0]), # spec id + parser.compile_filter(bits[1]), # source file + parser.compile_filter(bits[3]), # var name + ) + elif len(bits) > 1: + return SpecResultImgTagNode( + parser.compile_filter(bits[0]), # spec id + parser.compile_filter(bits[1]), # source file + bits[2:], # html attributes + ) + else: raise template.TemplateSyntaxError('\'spec\' tags must be in the form' ' "{% spec spec_id image %}" or' ' "{% spec spec_id image' ' as varname %}"') - spec_id = parser.compile_filter(args[1]) - source_image = parser.compile_filter(args[2]) - variable_name = arg_count > 3 and args[4] or None - return SpecNode(spec_id, source_image, variable_name) - spec = spec_tag = register.tag(spec) From e796b4cc61f6268c231b44df911dabf94bf8883b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 20 Oct 2012 22:15:25 -0400 Subject: [PATCH 076/527] Create ImageSpec subclasses Since the `ImageSpec` constructor will be accepting keyword arg hints, it can no longer accept the properties. --- imagekit/specs/__init__.py | 81 +++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index ccb4cb47..f9f79201 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -89,16 +89,36 @@ def source_receiver(self, sender, source_file, signal, info, **kwargs): class BaseImageSpec(object): + processors = None + """A list of processors to run on the original image.""" + format = None + """ + The format of the output file. If not provided, ImageSpecField will try to + guess the appropriate format based on the extension of the filename and the + format of the input image. + + """ + options = None + """ + A dictionary that will be passed to PIL's ``Image.save()`` method as keyword + arguments. Valid options vary between formats, but some examples include + ``quality``, ``optimize``, and ``progressive`` for JPEGs. See the PIL + documentation for others. + + """ + autoconvert = True + """ + Specifies whether automatic conversion using ``prepare_image()`` should be + performed prior to saving. - def __init__(self, processors=None, format=None, options=None, autoconvert=None): - self.processors = processors or self.processors or [] - self.format = format or self.format - self.options = options or self.options - self.autoconvert = self.autoconvert if autoconvert is None else autoconvert + """ + + def __init__(self): + self.processors = self.processors or [] def get_hash(self, source_file): return md5(''.join([ @@ -137,42 +157,29 @@ def apply(self, content, filename=None): class ImageSpec(BaseImageSpec): + storage = None + """A Django storage system to use to save the generated image.""" + image_cache_backend = None + """ + An object responsible for managing the state of cached files. Defaults to an + instance of ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` + + """ + image_cache_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY + """ + A dictionary containing callbacks that allow you to customize how and when + the image cache is validated. Defaults to + ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY``. - def __init__(self, processors=None, format=None, options=None, - storage=None, autoconvert=None, image_cache_backend=None, - image_cache_strategy=None): - """ - :param processors: A list of processors to run on the original image. - :param format: The format of the output file. If not provided, - ImageSpecField will try to guess the appropriate format based on the - extension of the filename and the format of the input image. - :param options: A dictionary that will be passed to PIL's - ``Image.save()`` method as keyword arguments. Valid options vary - between formats, but some examples include ``quality``, - ``optimize``, and ``progressive`` for JPEGs. See the PIL - documentation for others. - :param autoconvert: Specifies whether automatic conversion using - ``prepare_image()`` should be performed prior to saving. - :param image_field: The name of the model property that contains the - original image. - :param storage: A Django storage system to use to save the generated - image. - :param image_cache_backend: An object responsible for managing the state - of cached files. Defaults to an instance of - ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` - :param image_cache_strategy: A dictionary containing callbacks that - allow you to customize how and when the image cache is validated. - Defaults to ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY`` + """ - """ - super(ImageSpec, self).__init__(processors=processors, format=format, - options=options, autoconvert=autoconvert) - self.storage = storage or self.storage - self.image_cache_backend = image_cache_backend or self.image_cache_backend or get_default_image_cache_backend() - self.image_cache_strategy = StrategyWrapper(image_cache_strategy or self.image_cache_strategy) + def __init__(self, **kwargs): + super(ImageSpec, self).__init__() + self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() + self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) # TODO: I don't like this interface. Is there a standard Python one? pubsub? def _handle_source_event(self, event_name, source_file): @@ -205,7 +212,7 @@ def __init__(self, processors=None, format=None, options=None, raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - spec = ImageSpec(**spec_args) + spec = type('Spec', (ImageSpec,), spec_args) # TODO: Base class name on spec id? self._original_spec = spec From aa91a70e4642ec2843de354a8df129c1999626b8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 20 Oct 2012 22:53:55 -0400 Subject: [PATCH 077/527] Make specs know less about source files --- imagekit/files.py | 8 ++++++-- imagekit/specs/__init__.py | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index e04198d9..567468a7 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,6 +2,7 @@ from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode +from hashlib import md5 import os from .signals import before_access from .utils import (suggest_extension, format_to_mimetype, @@ -80,7 +81,10 @@ def __init__(self, spec, source_file): self.source_file = source_file def get_hash(self): - return self.spec.get_hash(self.source_file) + return md5(''.join([ + self.source_file.name, + self.spec.get_hash(), + ]).encode('utf-8')).hexdigest() def _require_file(self): before_access.send(sender=self, spec=self.spec, file=self) @@ -91,7 +95,7 @@ def name(self): source_filename = self.source_file.name filename = None if source_filename: - hash = self.spec.get_hash(self.source_file) + hash = self.get_hash() ext = suggest_extension(source_filename, self.spec.format) filename = os.path.normpath(os.path.join( settings.IMAGEKIT_CACHE_DIR, diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index f9f79201..e64f9766 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -120,9 +120,8 @@ class BaseImageSpec(object): def __init__(self): self.processors = self.processors or [] - def get_hash(self, source_file): + def get_hash(self): return md5(''.join([ - source_file.name, pickle.dumps(self.processors), str(self.format), pickle.dumps(self.options), From 12493b3a0da6cb5503aba11339d45456854155e8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 20 Oct 2012 23:21:01 -0400 Subject: [PATCH 078/527] Spec host must support kwarg "hints" The registry's `get_spec()` was already supporting kwargs as a means to provide information about the source to the spec constructor/factory function, but the ``SpecHost`` class wasn't capable of accepting any. This commit rectifies that. The main goal purpose of this is to allow a bound field (the file attached by ``ImageSpecFileDescriptor``)--and the attached model instance--to be taken into account during the spec instance creation. Related: #156 --- imagekit/models/fields/__init__.py | 4 ---- imagekit/models/fields/files.py | 5 +++-- imagekit/models/fields/utils.py | 3 ++- imagekit/specs/__init__.py | 5 ++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 0cb6443f..771c81ea 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -38,10 +38,6 @@ def __init__(self, processors=None, format=None, options=None, self.image_field = image_field - @property - def storage(self): - return self.spec.storage - def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) self.set_spec_id(cls, name) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 3c9ffd68..26037fda 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -6,7 +6,8 @@ class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): filename, ext = os.path.splitext(name) - ext = suggest_extension(name, self.field.spec.format) + spec = self.field.get_spec() # TODO: What "hints"? + ext = suggest_extension(name, spec.format) new_name = '%s%s' % (filename, ext) - content = self.field.spec.apply(content, new_name) + content = spec.apply(content, new_name) return super(ProcessedImageFieldFile, self).save(new_name, content, save) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 9490966f..0695212c 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -29,7 +29,8 @@ def __get__(self, instance, owner): self.attname)) else: source_file = image_fields[0] - file = ImageSpecCacheFile(self.field.spec, source_file) + spec = self.field.get_spec() # TODO: What "hints" should we pass here? + file = ImageSpecCacheFile(spec, source_file) instance.__dict__[self.attname] = file return file diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e64f9766..0e10c657 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -230,8 +230,7 @@ def set_spec_id(self, id): self.spec_id = id registry.register(id, self._original_spec) - @property - def spec(self): + def get_spec(self, **kwargs): """ Look up the spec by the spec id. We do this (instead of storing the spec as an attribute) so that users can override apps' specs--without @@ -241,7 +240,7 @@ def spec(self): """ if not getattr(self, 'spec_id', None): raise Exception('Object %s has no spec id.' % self) - return registry.get_spec(self.spec_id) + return registry.get_spec(self.spec_id, **kwargs) registry = SpecRegistry() From 0c4d9738c63e6dec565303488205b74074ea4de1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 20 Oct 2012 23:44:13 -0400 Subject: [PATCH 079/527] Add TODO --- imagekit/templatetags/imagekit_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index b092ca4f..959d4792 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -34,7 +34,7 @@ def get_spec(self, context): from ..utils import autodiscover autodiscover() spec_id = self._spec_id.resolve(context) - spec = specs.registry.get_spec(spec_id) + spec = specs.registry.get_spec(spec_id) # TODO: What "hints" here? if callable(spec): spec = spec() return spec From 3e2c3803ff1dbe353d2131ee6fcd7b13bb386e6d Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 20 Oct 2012 23:44:26 -0400 Subject: [PATCH 080/527] No need to call spec; the registry does that --- imagekit/templatetags/imagekit_tags.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit_tags.py index 959d4792..b0b981bf 100644 --- a/imagekit/templatetags/imagekit_tags.py +++ b/imagekit/templatetags/imagekit_tags.py @@ -35,8 +35,6 @@ def get_spec(self, context): autodiscover() spec_id = self._spec_id.resolve(context) spec = specs.registry.get_spec(spec_id) # TODO: What "hints" here? - if callable(spec): - spec = spec() return spec def get_source_file(self, context): From fa54b9b6ef7bdaf581e128b81013ebfdbadbe99c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 21 Oct 2012 17:55:18 -0400 Subject: [PATCH 081/527] Document file-generation aspect of specs --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index a616d754..94cf4c09 100644 --- a/README.rst +++ b/README.rst @@ -59,7 +59,8 @@ might be useful, for example, in view code, or in scripts: .. code-block:: python - ???????? + spec = Thumbnail() + new_file = spec.apply(source_file) More often, however, you'll want to register your spec with ImageKit: From 3dbb96ea40e8960bc524a1756919577df7f4e024 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 21 Oct 2012 17:57:53 -0400 Subject: [PATCH 082/527] Remove unused imports --- imagekit/utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 282b739a..a4712e4a 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -382,11 +382,9 @@ def autodiscover(): Copied from django.contrib.admin """ - import copy from django.conf import settings from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule - from .templatetags import imagekit_tags for app in settings.INSTALLED_APPS: mod = import_module(app) From d110b823470ccecc7b203238049ab21837821be6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 21 Oct 2012 17:59:56 -0400 Subject: [PATCH 083/527] Rename imagekit_tags to imagekit --- imagekit/templatetags/__init__.py | 1 - imagekit/templatetags/{imagekit_tags.py => imagekit.py} | 0 2 files changed, 1 deletion(-) rename imagekit/templatetags/{imagekit_tags.py => imagekit.py} (100%) diff --git a/imagekit/templatetags/__init__.py b/imagekit/templatetags/__init__.py index e0a23fc0..e69de29b 100644 --- a/imagekit/templatetags/__init__.py +++ b/imagekit/templatetags/__init__.py @@ -1 +0,0 @@ -from .imagekit_tags import spec diff --git a/imagekit/templatetags/imagekit_tags.py b/imagekit/templatetags/imagekit.py similarity index 100% rename from imagekit/templatetags/imagekit_tags.py rename to imagekit/templatetags/imagekit.py From 606f59a102fb69bb93ed4636b63b46e140e4eae4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 21 Oct 2012 21:52:59 -0400 Subject: [PATCH 084/527] Add docs page about configuration & optimization --- docs/configuration.rst | 137 +++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + 2 files changed, 138 insertions(+) create mode 100644 docs/configuration.rst diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 00000000..18b3595e --- /dev/null +++ b/docs/configuration.rst @@ -0,0 +1,137 @@ +.. _settings: + +Configuration +============= + + +Settings +-------- + +.. currentmodule:: django.conf.settings + + +.. attribute:: IMAGEKIT_CACHE_DIR + + :default: ``'CACHE/images'`` + + The directory to which image files will be cached. + + +.. attribute:: IMAGEKIT_DEFAULT_FILE_STORAGE + + :default: ``None`` + + The qualified class name of a Django storage backend to use to save the + cached images. If no value is provided for ``IMAGEKIT_DEFAULT_FILE_STORAGE``, + and none is specified by the spec definition, the storage of the source file + will be used. + + +.. attribute:: IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND + + :default: ``'imagekit.imagecache.backends.Simple'`` + + Specifies the class that will be used to validate cached image files. + + +.. attribute:: IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY + + :default: ``'imagekit.imagecache.strategies.JustInTime'`` + + The class responsible for specifying how and when cache files are + generated. + + +.. attribute:: IMAGEKIT_CACHE_BACKEND + + :default: If ``DEBUG`` is ``True``, ``'django.core.cache.backends.dummy.DummyCache'``. + Otherwise, ``'default'``. + + The Django cache backend to be used to store information like the state of + cached images (i.e. validated or not). + + +.. attribute:: IMAGEKIT_CACHE_PREFIX + + :default: ``'imagekit:'`` + + A cache prefix to be used when values are stored in ``IMAGEKIT_CACHE_BACKEND`` + + +Optimization +------------ + +Not surprisingly, the trick to getting the most out of ImageKit is to reduce the +number of I/O operations. This can be especially important if your source files +aren't stored on the same server as the application. + + +Image Cache Strategies +^^^^^^^^^^^^^^^^^^^^^^ + +An important way of reducing the number of I/O operations that ImageKit makes is +by controlling when cached images are validated. This is done through "image +cache strategies"—objects that associate signals dispatched on the source file +with file actions. The default image cache strategy is +``'imagekit.imagecache.strategies.JustInTime'``; it looks like this: + +.. code-block:: python + + class JustInTime(object): + def before_access(self, file): + validate_now(file) + +When this strategy is used, the cache file is validated only immediately before +it's required—for example, when you access its url, path, or contents. This +strategy is exceedingly safe: by guaranteeing the presence of the file before +accessing it, you run no risk of it not being there. However, this strategy can +also be costly: verifying the existence of the cache file every time you access +it can be slow—particularly if the file is on another server. For this reason, +ImageKit provides another strategy: ``imagekit.imagecache.strategies.Optimistic``. +Unlike the just-in-time strategy, it does not validate the cache file when it's +accessed, but rather only when the soure file is created or changed. Later, when +the cache file is accessed, it is presumed to still be present. + +If neither of these strategies suits your application, you can create your own +strategy class. For example, you may wish to validate the file immediately when +it's accessed, but schedule validation using Celery when the source file is +saved or changed: + +.. code-block:: python + + from imagekit.imagecache.actions import validate_now, deferred_validate + + class CustomImageCacheStrategy(object): + + def before_access(self, file): + validate_now(file) + + def on_source_created(self, file): + deferred_validate(file) + + def on_source_changed(self, file): + deferred_validate(file) + +To use this cache strategy, you need only set the ``IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY`` +setting, or set the ``image_cache_strategy`` attribute of your image spec. + + +Django Cache Backends +^^^^^^^^^^^^^^^^^^^^^ + +In the "Image Cache Strategies" section above, we said that the just-in-time +strategy verifies the existence of the cache file every time you access +it, however, that's not exactly true. Cache files are actually validated using +image cache backends, and the default (``imagekit.imagecache.backends.Simple``) +memoizes the cache state (valid or invalid) using Django's cache framework. By +default, ImageKit will use a dummy cache backend when your project is in debug +mode (``DEBUG = True``), and the "default" cache (from your ``CACHES`` setting) +when ``DEBUG`` is ``False``. Since other parts of your project may have +different cacheing needs, though, ImageKit has an ``IMAGEKIT_CACHE_BACKEND`` +setting, which allows you to specify a different cache. + +In most cases, you won't be deleting you cached files once they're created, so +using a cache with a large timeout is a great way to optimize your site. Using +a cache that never expires would essentially negate the cost of the just-in-time +strategy, giving you the benefit of generating images on demand without the cost +of unnecessary future filesystem checks. diff --git a/docs/index.rst b/docs/index.rst index 2c063856..54843519 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,6 +31,7 @@ Digging Deeper .. toctree:: + configuration apireference changelog From 8d3fcafcd9438c4897de568597cef77cf3d9a061 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 24 Oct 2012 21:50:53 -0400 Subject: [PATCH 085/527] Swap argument order for specs.register This will allow us to put the id in the inner Meta class. --- README.rst | 2 +- imagekit/specs/__init__.py | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/README.rst b/README.rst index 94cf4c09..242562ab 100644 --- a/README.rst +++ b/README.rst @@ -67,7 +67,7 @@ More often, however, you'll want to register your spec with ImageKit: .. code-block:: python from imagekit import specs - specs.register('myapp:fancy_thumbnail', Thumbnail) + specs.register(Thumbnail, 'myapp:fancy_thumbnail') Once a spec is registered with a unique name, you can start to take advantage of ImageKit's powerful utilities to automatically generate images for you... diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 0e10c657..af627d2e 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -36,7 +36,7 @@ def __init__(self): signal.connect(self.source_receiver) before_access.connect(self.before_access_receiver) - def register(self, id, spec): + def register(self, spec, id): if id in self._specs: raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec @@ -228,7 +228,7 @@ def set_spec_id(self, id): """ self.spec_id = id - registry.register(id, self._original_spec) + registry.register(self._original_spec, id) def get_spec(self, **kwargs): """ @@ -244,15 +244,7 @@ def get_spec(self, **kwargs): registry = SpecRegistry() - - -def register(id, spec=None): - if not spec: - def decorator(cls): - registry.register(id, cls) - return cls - return decorator - registry.register(id, spec) +register = registry.register def unregister(id, spec): From bdec396180643dc143e4fe358a7c77536ac7ed4d Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 24 Oct 2012 22:23:32 -0400 Subject: [PATCH 086/527] Support inner `Config` class for id, sources Closes #164 --- imagekit/exceptions.py | 4 ++++ imagekit/specs/__init__.py | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index 55cf144f..b453f16c 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -12,3 +12,7 @@ class UnknownExtensionError(Exception): class UnknownFormatError(Exception): pass + + +class MissingSpecId(Exception): + pass diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index af627d2e..3d5e0cad 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -2,7 +2,8 @@ from hashlib import md5 import os import pickle -from ..exceptions import UnknownExtensionError, AlreadyRegistered, NotRegistered +from ..exceptions import (UnknownExtensionError, AlreadyRegistered, + NotRegistered, MissingSpecId) from ..files import ImageSpecCacheFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper @@ -36,11 +37,25 @@ def __init__(self): signal.connect(self.source_receiver) before_access.connect(self.before_access_receiver) - def register(self, spec, id): + def register(self, spec, id=None): + config = getattr(spec, 'Config', None) + + if id is None: + id = getattr(config, 'id', None) + + if id is None: + raise MissingSpecId('No id provided for %s. You must either pass an' + ' id to the register function, or add an id' + ' attribute to the inner Config class of your' + ' spec.' % spec) + if id in self._specs: raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec + for source in getattr(config, 'sources', None) or []: + self.add_source(source, id) + def unregister(self, id, spec): try: del self._specs[id] From adf143edc5374a635024d09d08a445a82145a6fb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 24 Oct 2012 22:29:21 -0400 Subject: [PATCH 087/527] `add_source` -> `add_sources`; switch argument order --- imagekit/models/fields/__init__.py | 4 ++-- imagekit/specs/__init__.py | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 771c81ea..3f98f352 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -43,8 +43,8 @@ def contribute_to_class(self, cls, name): self.set_spec_id(cls, name) # Add the model and field as a source for this spec id - specs.registry.add_source(ImageFieldSpecSource(cls, self.image_field), - self.spec_id) + specs.registry.add_sources(self.spec_id, + [ImageFieldSpecSource(cls, self.image_field)]) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 3d5e0cad..3e761a6d 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -53,8 +53,8 @@ def register(self, spec, id=None): raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec - for source in getattr(config, 'sources', None) or []: - self.add_source(source, id) + sources = getattr(config, 'sources', None) or [] + self.add_sources(id, sources) def unregister(self, id, spec): try: @@ -72,14 +72,15 @@ def get_spec(self, id, **kwargs): else: return spec - def add_source(self, source, spec_id): + def add_sources(self, spec_id, sources): """ - Associates a source with a spec id + Associates sources with a spec id """ - if source not in self._sources: - self._sources[source] = set() - self._sources[source].add(spec_id) + for source in sources: + if source not in self._sources: + self._sources[source] = set() + self._sources[source].add(spec_id) def before_access_receiver(self, sender, spec, file, **kwargs): spec.image_cache_strategy.invoke_callback('before_access', file) From d27836983abc2933158325138badf24f923a1752 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Wed, 24 Oct 2012 23:30:37 -0400 Subject: [PATCH 088/527] Use nose to run tests Closes #160 --- requirements.txt | 5 +++++ tests/settings.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/requirements.txt b/requirements.txt index 5161716e..23b38e9c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,8 @@ Django>=1.3.1 django-appconf>=0.5 PIL>=1.1.7 + +# Required for tests +nose==1.2.1 +nose-progressive==1.3 +django-nose==1.1 diff --git a/tests/settings.py b/tests/settings.py index f034e9c0..11113f6f 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -26,6 +26,21 @@ 'django.contrib.contenttypes', 'imagekit', 'core', + 'django_nose', +] + +TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' +NOSE_ARGS = [ + '-s', + '--with-progressive', + + # When the tests are run --with-coverage, these args configure coverage + # reporting (requires coverage to be installed). + # Without the --with-coverage flag, they have no effect. + '--cover-tests', + '--cover-html', + '--cover-package=imagekit', + '--cover-html-dir=%s' % os.path.join(BASE_PATH, 'cover') ] DEBUG = True From 84f3b6475bce1890f6ba95907d1f40f6c681ee2f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 24 Oct 2012 22:41:35 -0400 Subject: [PATCH 089/527] Add `files()` generator. Re: #165 --- imagekit/specs/sources.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/imagekit/specs/sources.py b/imagekit/specs/sources.py index 15c852e6..3be4a7e8 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sources.py @@ -115,5 +115,9 @@ def __init__(self, model_class, image_field): self.image_field = image_field signal_router.add(self) + def files(self): + for instance in self.model_class.objects.all(): + yield getattr(instance, self.image_field) + signal_router = ModelSignalRouter() From fb8c411f751b8989f61dd1ca888cc9bca31216f8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 24 Oct 2012 23:36:00 -0400 Subject: [PATCH 090/527] Create new cache warming command Replaces ikcachevalidate and ikcacheinvalidate, and uses the "sources" abstraction. Closes #165 --- .../management/commands/ikcacheinvalidate.py | 14 -------- .../management/commands/ikcachevalidate.py | 30 ---------------- .../management/commands/warmimagecache.py | 36 +++++++++++++++++++ imagekit/specs/__init__.py | 6 ++++ imagekit/utils.py | 22 ------------ 5 files changed, 42 insertions(+), 66 deletions(-) delete mode 100644 imagekit/management/commands/ikcacheinvalidate.py delete mode 100644 imagekit/management/commands/ikcachevalidate.py create mode 100644 imagekit/management/commands/warmimagecache.py diff --git a/imagekit/management/commands/ikcacheinvalidate.py b/imagekit/management/commands/ikcacheinvalidate.py deleted file mode 100644 index 2b6e915f..00000000 --- a/imagekit/management/commands/ikcacheinvalidate.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.core.management.base import BaseCommand -from django.db.models.loading import cache -from ...utils import invalidate_app_cache - - -class Command(BaseCommand): - help = ('Invalidates the image cache for a list of apps.') - args = '[apps]' - requires_model_validation = True - can_import_settings = True - - def handle(self, *args, **options): - apps = args or cache.app_models.keys() - invalidate_app_cache(apps) diff --git a/imagekit/management/commands/ikcachevalidate.py b/imagekit/management/commands/ikcachevalidate.py deleted file mode 100644 index 8e9fc6c4..00000000 --- a/imagekit/management/commands/ikcachevalidate.py +++ /dev/null @@ -1,30 +0,0 @@ -from optparse import make_option -from django.core.management.base import BaseCommand -from django.db.models.loading import cache -from ...utils import validate_app_cache - - -class Command(BaseCommand): - help = ('Validates the image cache for a list of apps.') - args = '[apps]' - requires_model_validation = True - can_import_settings = True - - option_list = BaseCommand.option_list + ( - make_option('--force-revalidation', - dest='force_revalidation', - action='http://github.com/store_true', - default=False, - help='Invalidate each image file before validating it, thereby' - ' ensuring its revalidation. This is very similar to' - ' running ikcacheinvalidate and then running' - ' ikcachevalidate; the difference being that this option' - ' causes files to be invalidated and validated' - ' one-at-a-time, whereas running the two commands in series' - ' would invalidate all images before validating any.' - ), - ) - - def handle(self, *args, **options): - apps = args or cache.app_models.keys() - validate_app_cache(apps, options['force_revalidation']) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py new file mode 100644 index 00000000..8c9efcbb --- /dev/null +++ b/imagekit/management/commands/warmimagecache.py @@ -0,0 +1,36 @@ +from optparse import make_option +from django.core.management.base import BaseCommand +import re +from ...files import ImageSpecCacheFile +from ...specs import registry + + +class Command(BaseCommand): + help = ('Warm the image cache for the specified specs (or all specs if none' + ' was provided). Simple wildcard matching (using asterisks) is' + ' supported.') + args = '[spec_ids]' + + def handle(self, *args, **options): + specs = registry.get_spec_ids() + + if args: + patterns = self.compile_patterns(args) + specs = (id for id in specs if any(p.match(id) for p in patterns)) + + for spec_id in specs: + self.stdout.write('Validating spec: %s\n' % spec_id) + spec = registry.get_spec(spec_id) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) + for source in registry.get_sources(spec_id): + for source_file in source.files(): + if source_file: + self.stdout.write(' %s\n' % source_file) + try: + # TODO: Allow other validation actions through command option + ImageSpecCacheFile(spec, source_file).validate() + except Exception, err: + # TODO: How should we handle failures? Don't want to error, but should call it out more than this. + self.stdout.write(' FAILED: %s\n' % err) + + def compile_patterns(self, spec_ids): + return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in spec_ids] diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 3e761a6d..dc335930 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -72,6 +72,9 @@ def get_spec(self, id, **kwargs): else: return spec + def get_spec_ids(self): + return self._specs.keys() + def add_sources(self, spec_id, sources): """ Associates sources with a spec id @@ -82,6 +85,9 @@ def add_sources(self, spec_id, sources): self._sources[source] = set() self._sources[source].add(spec_id) + def get_sources(self, spec_id): + return [source for source in self._sources if spec_id in self._sources[source]] + def before_access_receiver(self, sender, spec, file, **kwargs): spec.image_cache_strategy.invoke_callback('before_access', file) diff --git a/imagekit/utils.py b/imagekit/utils.py index a4712e4a..7495238e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -146,28 +146,6 @@ def _get_models(apps): return models -def invalidate_app_cache(apps): - for model in _get_models(apps): - print 'Invalidating cache for "%s.%s"' % (model._meta.app_label, model.__name__) - for obj in model._default_manager.order_by('-pk'): - for f in get_spec_files(obj): - f.invalidate() - - -def validate_app_cache(apps, force_revalidation=False): - for model in _get_models(apps): - for obj in model._default_manager.order_by('-pk'): - model_name = '%s.%s' % (model._meta.app_label, model.__name__) - if force_revalidation: - print 'Invalidating & validating cache for "%s"' % model_name - else: - print 'Validating cache for "%s"' % model_name - for f in get_spec_files(obj): - if force_revalidation: - f.invalidate() - f.validate() - - def suggest_extension(name, format): original_extension = os.path.splitext(name)[1] try: From 9973e80a37d775cda07868efe8b35a55da7e3b31 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Wed, 24 Oct 2012 23:45:00 -0400 Subject: [PATCH 091/527] Add test requirements to setup --- setup.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup.py b/setup.py index 6f662f93..9764b065 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,11 @@ packages=find_packages(), zip_safe=False, include_package_data=True, + tests_require=[ + 'nose==1.2.1', + 'nose-progressive==1.3', + 'django-nose==1.1', + ], install_requires=[ 'django-appconf>=0.5', ], From 006ff54fa865942d533298bf0eea8e71d12576b5 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Oct 2012 20:01:11 -0400 Subject: [PATCH 092/527] Clean up version meta. --- imagekit/__init__.py | 37 +------------------------------------ imagekit/pkgmeta.py | 5 +++++ setup.py | 8 +++++--- 3 files changed, 11 insertions(+), 39 deletions(-) create mode 100644 imagekit/pkgmeta.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index f4fd2271..74808d32 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,38 +1,3 @@ from . import conf from .specs import ImageSpec - - -__title__ = 'django-imagekit' -__author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = (2, 0, 1, 'final', 0) -__license__ = 'BSD' - - -def get_version(version=None): - """Derives a PEP386-compliant version number from VERSION.""" - if version is None: - version = __version__ - assert len(version) == 5 - assert version[3] in ('alpha', 'beta', 'rc', 'final') - - # Now build the two parts of the version number: - # main = X.Y[.Z] - # sub = .devN - for pre-alpha releases - # | {a|b|c}N - for alpha, beta and rc releases - - parts = 2 if version[2] == 0 else 3 - main = '.'.join(str(x) for x in version[:parts]) - - sub = '' - if version[3] == 'alpha' and version[4] == 0: - # At the toplevel, this would cause an import loop. - from django.utils.version import get_svn_revision - svn_revision = get_svn_revision()[4:] - if svn_revision != 'unknown': - sub = '.dev%s' % svn_revision - - elif version[3] != 'final': - mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'c'} - sub = mapping[version[3]] + str(version[4]) - - return main + sub +from .pkgmeta import * diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py new file mode 100644 index 00000000..20e62db6 --- /dev/null +++ b/imagekit/pkgmeta.py @@ -0,0 +1,5 @@ +__title__ = 'django-imagekit' +__author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' +__version__ = '3.0a1' +__license__ = 'BSD' +__all__ = ['__title__', '__author__', '__version__', '__license__'] diff --git a/setup.py b/setup.py index 9764b065..985e103b 100644 --- a/setup.py +++ b/setup.py @@ -11,12 +11,14 @@ read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read() -# Dynamically calculate the version based on imagekit.VERSION. -version = __import__('imagekit').get_version() +# Load package meta from the pkgmeta module without loading imagekit. +pkgmeta = {} +execfile(os.path.join(os.path.dirname(__file__), + 'imagekit', 'pkgmeta.py'), pkgmeta) setup( name='django-imagekit', - version=version, + version=pkgmeta['__version__'], description='Automated image processing for Django models.', long_description=read(os.path.join(os.path.dirname(__file__), 'README.rst')), author='Justin Driscoll', From 76b9ebbab455e2ec7c99b3dbdd2522f0b067f270 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Oct 2012 22:25:18 -0400 Subject: [PATCH 093/527] Omit missing kwargs so as not to override defaults The default image cache strategy was being overridden, which prevented images from being generated. --- imagekit/specs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index dc335930..3878bc91 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -233,7 +233,7 @@ def __init__(self, processors=None, format=None, options=None, raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - spec = type('Spec', (ImageSpec,), spec_args) # TODO: Base class name on spec id? + spec = type('Spec', (ImageSpec,), dict((k, v) for k, v in spec_args.items() if v is not None)) # TODO: Base class name on spec id? self._original_spec = spec From 570e7bd640b5b84aefb3ccb4c836cf5b6b08a22c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Oct 2012 22:31:37 -0400 Subject: [PATCH 094/527] Simplify SpecHost creation --- imagekit/specs/__init__.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 3878bc91..2d1ad2c3 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -214,26 +214,16 @@ class SpecHost(object): spec registry. """ - def __init__(self, processors=None, format=None, options=None, - storage=None, autoconvert=None, image_cache_backend=None, - image_cache_strategy=None, spec=None, spec_id=None): - - spec_args = dict( - processors=processors, - format=format, - options=options, - storage=storage, - autoconvert=autoconvert, - image_cache_backend=image_cache_backend, - image_cache_strategy=image_cache_strategy, - ) - - if any(v is not None for v in spec_args.values()): + def __init__(self, spec=None, spec_id=None, **kwargs): + + spec_args = dict((k, v) for k, v in kwargs.items() if v is not None) + + if spec_args: if spec: raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - spec = type('Spec', (ImageSpec,), dict((k, v) for k, v in spec_args.items() if v is not None)) # TODO: Base class name on spec id? + spec = type('Spec', (ImageSpec,), spec_args) # TODO: Base class name on spec id? self._original_spec = spec From 6377f89e853b1c0beb29374f15c85105b255c3a0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Oct 2012 22:43:10 -0400 Subject: [PATCH 095/527] IKContentFile must have name attr --- imagekit/files.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/imagekit/files.py b/imagekit/files.py index 567468a7..c781c356 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -148,6 +148,10 @@ def __init__(self, filename, content, format=None): mimetype = extension_to_mimetype(ext) self.file.content_type = mimetype + @property + def name(self): + return self.file.name + def __str__(self): return smart_str(self.file.name or '') From 56f8d1b8bcdc8f2fb837167a7b26ea816ddf95db Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Oct 2012 22:46:28 -0400 Subject: [PATCH 096/527] Create form field class; re: #163 --- imagekit/forms/__init__.py | 1 + imagekit/forms/fields.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 imagekit/forms/__init__.py create mode 100644 imagekit/forms/fields.py diff --git a/imagekit/forms/__init__.py b/imagekit/forms/__init__.py new file mode 100644 index 00000000..8086e947 --- /dev/null +++ b/imagekit/forms/__init__.py @@ -0,0 +1 @@ +from .fields import ProcessedImageField diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py new file mode 100644 index 00000000..19a43873 --- /dev/null +++ b/imagekit/forms/fields.py @@ -0,0 +1,25 @@ +from django.forms import ImageField +from ..specs import SpecHost + + +class ProcessedImageField(ImageField, SpecHost): + + def __init__(self, processors=None, format=None, options=None, + autoconvert=True, spec=None, spec_id=None, *args, **kwargs): + + if spec_id is None: + spec_id = '??????' # FIXME: Wher should we get this? + + SpecHost.__init__(self, processors=processors, format=format, + options=options, autoconvert=autoconvert, spec=spec, + spec_id=spec_id) + super(ProcessedImageField, self).__init__(*args, **kwargs) + + def clean(self, data, initial=None): + data = super(ProcessedImageField, self).clean(data, initial) + + if data: + spec = self.get_spec() # HINTS?!?!?!?!?! + data = spec.apply(data, data.name) + + return data From 64d95768f8192b11b8d390c198a2eee95ec82373 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 2 Nov 2012 00:27:29 -0400 Subject: [PATCH 097/527] Extract GeneratedImageCacheFile As mentioned in #167, we want to be forward thinking and allow for a hypothetical spec supertype which has the same functionality as an image spec but doesn't require a source file: a generator. To this end, I've renamed `ImageSpec.apply()` to `ImageSpec.generate()` and extracted a `GeneratedImageCacheFile` base class from `ImageSpecCacheFile`, which supports the more general interface of a generator--namely, a `generate()` method with arbitrary args and kwargs. --- imagekit/files.py | 125 ++++++++++++++++++++------------ imagekit/imagecache/backends.py | 2 +- imagekit/specs/__init__.py | 8 +- 3 files changed, 84 insertions(+), 51 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index c781c356..57b73d6b 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -4,8 +4,9 @@ from django.utils.encoding import smart_str, smart_unicode from hashlib import md5 import os +import pickle from .signals import before_access -from .utils import (suggest_extension, format_to_mimetype, +from .utils import (suggest_extension, format_to_mimetype, format_to_extension, extension_to_mimetype, get_logger, get_singleton) @@ -71,63 +72,95 @@ def close(self): file.close() -class ImageSpecCacheFile(BaseIKFile, ImageFile): - def __init__(self, spec, source_file): - storage = (spec.storage or - get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') if settings.IMAGEKIT_DEFAULT_FILE_STORAGE - else source_file.storage) - super(ImageSpecCacheFile, self).__init__(storage=storage) - self.spec = spec - self.source_file = source_file - - def get_hash(self): - return md5(''.join([ - self.source_file.name, - self.spec.get_hash(), - ]).encode('utf-8')).hexdigest() +class GeneratedImageCacheFile(BaseIKFile, ImageFile): + """ + A cache file that represents the result of a generator. Creating an instance + of this class is not enough to trigger the creation of the cache file. In + fact, one of the main points of this class is to allow the creation of the + file to be deferred until the time that the image cache strategy requires + it. - def _require_file(self): - before_access.send(sender=self, spec=self.spec, file=self) - return super(ImageSpecCacheFile, self)._require_file() + """ + def __init__(self, generator, *args, **kwargs): + """ + :param generator: The object responsible for generating a new image. + :param args: Positional arguments that will be passed to the generator's + ``generate()`` method when the generation is called for. + :param kwargs: Keyword arguments that will be apssed to the generator's + ``generate()`` method when the generation is called for. + + """ + self.generator = generator + self.args = args + self.kwargs = kwargs + storage = getattr(generator, 'storage', None) + if not storage and settings.IMAGEKIT_DEFAULT_FILE_STORAGE: + storage = get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend') + super(GeneratedImageCacheFile, self).__init__(storage=storage) @property def name(self): - source_filename = self.source_file.name - filename = None - if source_filename: - hash = self.get_hash() - ext = suggest_extension(source_filename, self.spec.format) - filename = os.path.normpath(os.path.join( - settings.IMAGEKIT_CACHE_DIR, - os.path.splitext(source_filename)[0], - '%s%s' % (hash, ext))) - - return filename + # FIXME: This won't work if args or kwargs contain a file object. It probably won't work in many other cases as well. Better option? + hash = md5(''.join([ + pickle.dumps(self.args), + pickle.dumps(self.kwargs), + self.generator.get_hash(), + ]).encode('utf-8')).hexdigest() + ext = format_to_extension(self.generator.format) + return os.path.join(settings.IMAGEKIT_CACHE_DIR, + '%s%s' % (hash, ext)) + + def _require_file(self): + before_access.send(sender=self, generator=self.generator, file=self) + return super(GeneratedImageCacheFile, self)._require_file() def clear(self): - return self.spec.image_cache_backend.clear(self) + return self.generator.image_cache_backend.clear(self) def invalidate(self): - return self.spec.image_cache_backend.invalidate(self) + return self.generator.image_cache_backend.invalidate(self) def validate(self): - return self.spec.image_cache_backend.validate(self) + return self.generator.image_cache_backend.validate(self) def generate(self): - if self.source_file: # TODO: Should we error here or something if the source_file doesn't exist? - # Process the original image file. - content = self.spec.apply(self.source_file) - actual_name = self.storage.save(self.name, content) - - if actual_name != self.name: - get_logger().warning('The storage backend %s did not save the file' - ' with the requested name ("%s") and instead used' - ' "%s". This may be because a file already existed with' - ' the requested name. If so, you may have meant to call' - ' validate() instead of generate(), or there may be a' - ' race condition in the image cache backend %s. The' - ' saved file will not be used.' % (self.storage, - self.name, actual_name, self.spec.image_cache_backend)) + # Generate the file + content = self.generator.generate(*self.args, **self.kwargs) + actual_name = self.storage.save(self.name, content) + + if actual_name != self.name: + get_logger().warning('The storage backend %s did not save the file' + ' with the requested name ("%s") and instead used' + ' "%s". This may be because a file already existed with' + ' the requested name. If so, you may have meant to call' + ' validate() instead of generate(), or there may be a' + ' race condition in the image cache backend %s. The' + ' saved file will not be used.' % (self.storage, + self.name, actual_name, + self.generator.image_cache_backend)) + + +class ImageSpecCacheFile(GeneratedImageCacheFile): + def __init__(self, generator, source_file): + super(ImageSpecCacheFile, self).__init__(generator, + source_file=source_file) + if not self.storage: + self.storage = source_file.storage + + @property + def name(self): + source_filename = self.kwargs['source_file'].name + hash = md5(''.join([ + source_filename, + self.generator.get_hash(), + ]).encode('utf-8')).hexdigest() + # TODO: Since specs can now be dynamically generated using hints, can we move this into the spec constructor? i.e. set self.format if not defined. This would get us closer to making ImageSpecCacheFile == GeneratedImageCacheFile + ext = suggest_extension(source_filename, self.generator.format) + return os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (hash, ext))) class IKContentFile(ContentFile): diff --git a/imagekit/imagecache/backends.py b/imagekit/imagecache/backends.py index 922b1f47..c31002f0 100644 --- a/imagekit/imagecache/backends.py +++ b/imagekit/imagecache/backends.py @@ -27,7 +27,7 @@ def cache(self): def get_key(self, file): from django.conf import settings - return '%s%s-valid' % (settings.IMAGEKIT_CACHE_PREFIX, file.get_hash()) + return '%s%s-valid' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) def is_invalid(self, file): key = self.get_key(file) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 2d1ad2c3..2d9b2702 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -88,8 +88,8 @@ def add_sources(self, spec_id, sources): def get_sources(self, spec_id): return [source for source in self._sources if spec_id in self._sources[source]] - def before_access_receiver(self, sender, spec, file, **kwargs): - spec.image_cache_strategy.invoke_callback('before_access', file) + def before_access_receiver(self, sender, generator, file, **kwargs): + generator.image_cache_strategy.invoke_callback('before_access', file) def source_receiver(self, sender, source_file, signal, info, **kwargs): """ @@ -150,8 +150,8 @@ def get_hash(self): str(self.autoconvert), ]).encode('utf-8')).hexdigest() - def apply(self, content, filename=None): - img = open_image(content) + def generate(self, source_file, filename=None): + img = open_image(source_file) original_format = img.format # Run the processors From e56d687bb0bd9c42c21507107c875ed6d1576453 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 2 Nov 2012 22:17:25 -0400 Subject: [PATCH 098/527] Name can be set explicitly on GeneratedImageCacheFile --- imagekit/files.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 57b73d6b..fddcce22 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -81,7 +81,7 @@ class GeneratedImageCacheFile(BaseIKFile, ImageFile): it. """ - def __init__(self, generator, *args, **kwargs): + def __init__(self, generator, name=None, *args, **kwargs): """ :param generator: The object responsible for generating a new image. :param args: Positional arguments that will be passed to the generator's @@ -90,6 +90,7 @@ def __init__(self, generator, *args, **kwargs): ``generate()`` method when the generation is called for. """ + self._name = name self.generator = generator self.args = args self.kwargs = kwargs @@ -99,8 +100,7 @@ def __init__(self, generator, *args, **kwargs): 'file storage backend') super(GeneratedImageCacheFile, self).__init__(storage=storage) - @property - def name(self): + def get_default_filename(self): # FIXME: This won't work if args or kwargs contain a file object. It probably won't work in many other cases as well. Better option? hash = md5(''.join([ pickle.dumps(self.args), @@ -111,6 +111,14 @@ def name(self): return os.path.join(settings.IMAGEKIT_CACHE_DIR, '%s%s' % (hash, ext)) + def _get_name(self): + return self._name or self.get_default_filename() + + def _set_name(self, value): + self._name = value + + name = property(_get_name, _set_name) + def _require_file(self): before_access.send(sender=self, generator=self.generator, file=self) return super(GeneratedImageCacheFile, self)._require_file() @@ -148,8 +156,7 @@ def __init__(self, generator, source_file): if not self.storage: self.storage = source_file.storage - @property - def name(self): + def get_default_filename(self): source_filename = self.kwargs['source_file'].name hash = md5(''.join([ source_filename, From 5494ee7fc148acd1e75714b130551632a7380373 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 3 Nov 2012 00:08:47 -0400 Subject: [PATCH 099/527] Clarify relationship between BaseImageSpec and ImageSpec --- imagekit/specs/__init__.py | 80 +++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 2d9b2702..36cb1023 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -111,6 +111,52 @@ def source_receiver(self, sender, source_file, signal, info, **kwargs): class BaseImageSpec(object): + """ + An object that defines how an new image should be generated from a source + image. + + """ + + storage = None + """A Django storage system to use to save the generated image.""" + + image_cache_backend = None + """ + An object responsible for managing the state of cached files. Defaults to an + instance of ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` + + """ + + image_cache_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY + """ + A dictionary containing callbacks that allow you to customize how and when + the image cache is validated. Defaults to + ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY``. + + """ + + def __init__(self, **kwargs): + self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() + self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) + + def get_hash(self): + raise NotImplementedError + + def generate(self, source_file, filename=None): + raise NotImplementedError + + # TODO: I don't like this interface. Is there a standard Python one? pubsub? + def _handle_source_event(self, event_name, source_file): + file = ImageSpecCacheFile(self, source_file) + self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) + + +class ImageSpec(BaseImageSpec): + """ + An object that defines how to generate a new image from a source file using + PIL-based processors. (See :mod:`imagekit.processors`) + + """ processors = None """A list of processors to run on the original image.""" @@ -139,8 +185,9 @@ class BaseImageSpec(object): """ - def __init__(self): + def __init__(self, **kwargs): self.processors = self.processors or [] + super(ImageSpec, self).__init__() def get_hash(self): return md5(''.join([ @@ -177,37 +224,6 @@ def generate(self, source_file, filename=None): return content -class ImageSpec(BaseImageSpec): - - storage = None - """A Django storage system to use to save the generated image.""" - - image_cache_backend = None - """ - An object responsible for managing the state of cached files. Defaults to an - instance of ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` - - """ - - image_cache_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY - """ - A dictionary containing callbacks that allow you to customize how and when - the image cache is validated. Defaults to - ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY``. - - """ - - def __init__(self, **kwargs): - super(ImageSpec, self).__init__() - self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() - self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) - - # TODO: I don't like this interface. Is there a standard Python one? pubsub? - def _handle_source_event(self, event_name, source_file): - file = ImageSpecCacheFile(self, source_file) - self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) - - class SpecHost(object): """ An object that ostensibly has a spec attribute but really delegates to the From f9e2ce864916dca725954113716955b9b23a313f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 3 Nov 2012 00:27:03 -0400 Subject: [PATCH 100/527] Add TODO --- imagekit/specs/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 36cb1023..ae1ba65b 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -220,6 +220,7 @@ def generate(self, source_file, filename=None): format = format or img.format or original_format or 'JPEG' imgfile = img_to_fobj(img, format, **options) + # TODO: Is this the right place to wrap the file? Can we use a mixin instead? Is it even still having the desired effect? Re: #111 content = IKContentFile(filename, imgfile.read(), format=format) return content From 8266099ae8ba0ff3488acf30f93557da0681da3e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 21:33:05 -0500 Subject: [PATCH 101/527] Clean up tests dir --- Makefile | 6 ++++++ tests/{core => }/assets/Lenna.png | Bin .../assets/lenna-800x600-white-border.jpg | Bin tests/{core => }/assets/lenna-800x600.jpg | Bin tests/core/__init__.py | 0 tests/{core => }/models.py | 0 tests/run_tests.sh | 6 ------ tests/settings.py | 2 +- tests/{core => }/tests.py | 2 +- tests/{core/testutils.py => utils.py} | 0 tox.ini | 4 +--- 11 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 Makefile rename tests/{core => }/assets/Lenna.png (100%) rename tests/{core => }/assets/lenna-800x600-white-border.jpg (100%) rename tests/{core => }/assets/lenna-800x600.jpg (100%) delete mode 100644 tests/core/__init__.py rename tests/{core => }/models.py (100%) delete mode 100755 tests/run_tests.sh rename tests/{core => }/tests.py (98%) rename tests/{core/testutils.py => utils.py} (100%) diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..65cd5913 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +test: + export PYTHONPATH=$(PWD):$(PYTHONPATH); \ + django-admin.py test --settings=tests.settings tests + + +.PHONY: test diff --git a/tests/core/assets/Lenna.png b/tests/assets/Lenna.png similarity index 100% rename from tests/core/assets/Lenna.png rename to tests/assets/Lenna.png diff --git a/tests/core/assets/lenna-800x600-white-border.jpg b/tests/assets/lenna-800x600-white-border.jpg similarity index 100% rename from tests/core/assets/lenna-800x600-white-border.jpg rename to tests/assets/lenna-800x600-white-border.jpg diff --git a/tests/core/assets/lenna-800x600.jpg b/tests/assets/lenna-800x600.jpg similarity index 100% rename from tests/core/assets/lenna-800x600.jpg rename to tests/assets/lenna-800x600.jpg diff --git a/tests/core/__init__.py b/tests/core/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/core/models.py b/tests/models.py similarity index 100% rename from tests/core/models.py rename to tests/models.py diff --git a/tests/run_tests.sh b/tests/run_tests.sh deleted file mode 100755 index 6d3f37ba..00000000 --- a/tests/run_tests.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -PYTHONPATH=$PWD:$PWD/..${PYTHONPATH:+:$PYTHONPATH} -export PYTHONPATH - -echo "Running django-imagekit tests..." -django-admin.py test core --settings=settings diff --git a/tests/settings.py b/tests/settings.py index 11113f6f..3272aee0 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -25,7 +25,7 @@ 'django.contrib.auth', 'django.contrib.contenttypes', 'imagekit', - 'core', + 'tests', 'django_nose', ] diff --git a/tests/core/tests.py b/tests/tests.py similarity index 98% rename from tests/core/tests.py rename to tests/tests.py index 4998ce55..7afeb89d 100644 --- a/tests/core/tests.py +++ b/tests/tests.py @@ -8,7 +8,7 @@ from imagekit.exceptions import UnknownFormatError from .models import (Photo, AbstractImageModel, ConcreteImageModel1, ConcreteImageModel2) -from .testutils import create_photo, pickleback +from .utils import create_photo, pickleback class IKTest(TestCase): diff --git a/tests/core/testutils.py b/tests/utils.py similarity index 100% rename from tests/core/testutils.py rename to tests/utils.py diff --git a/tox.ini b/tox.ini index 72bf2068..383c1f82 100644 --- a/tox.ini +++ b/tox.ini @@ -4,9 +4,7 @@ envlist = py26-django14, py26-django13, py26-django12 [testenv] -changedir = tests -setenv = PYTHONPATH = {toxinidir}/tests -commands = django-admin.py test core --settings=settings +commands = make test [testenv:py27-django14] basepython = python2.7 From 56f1ccb8a8e7baa8f54b527a569688eb8431a4de Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 21:54:15 -0500 Subject: [PATCH 102/527] Separate test_utils module --- tests/test_utils.py | 23 +++++++++++++++++++++++ tests/tests.py | 18 ------------------ 2 files changed, 23 insertions(+), 18 deletions(-) create mode 100644 tests/test_utils.py diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..f4c777ec --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,23 @@ +from imagekit.exceptions import UnknownFormatError, UnknownExtensionError +from imagekit.utils import extension_to_format, format_to_extension +from nose.tools import eq_, raises + + +def test_extension_to_format(): + eq_(extension_to_format('.jpeg'), 'JPEG') + eq_(extension_to_format('.rgba'), 'SGI') + + +def test_format_to_extension_no_init(): + eq_(format_to_extension('PNG'), '.png') + eq_(format_to_extension('ICO'), '.ico') + + +@raises(UnknownFormatError) +def test_unknown_format(): + format_to_extension('TXT') + + +@raises(UnknownExtensionError) +def test_unknown_extension(): + extension_to_format('.txt') diff --git a/tests/tests.py b/tests/tests.py index 7afeb89d..9dab0c8b 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -4,8 +4,6 @@ from django.test import TestCase -from imagekit import utils -from imagekit.exceptions import UnknownFormatError from .models import (Photo, AbstractImageModel, ConcreteImageModel1, ConcreteImageModel2) from .utils import create_photo, pickleback @@ -48,22 +46,6 @@ def test_thumbnail_source_file(self): self.photo.thumbnail.source_file, self.photo.original_image) -class IKUtilsTest(TestCase): - def test_extension_to_format(self): - self.assertEqual(utils.extension_to_format('.jpeg'), 'JPEG') - self.assertEqual(utils.extension_to_format('.rgba'), 'SGI') - - with self.assertRaises(utils.UnknownExtensionError): - utils.extension_to_format('.txt') - - def test_format_to_extension_no_init(self): - self.assertEqual(utils.format_to_extension('PNG'), '.png') - self.assertEqual(utils.format_to_extension('ICO'), '.ico') - - with self.assertRaises(UnknownFormatError): - utils.format_to_extension('TXT') - - class PickleTest(TestCase): def test_model(self): ph = pickleback(create_photo('pickletest.jpg')) From 6255b93b78f9275f73b25c4ec0dd67192ed294ff Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 21:56:05 -0500 Subject: [PATCH 103/527] Add some processor tests --- tests/test_processors.py | 31 +++++++++++++++++++++++++++++++ tests/utils.py | 16 +++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 tests/test_processors.py diff --git a/tests/test_processors.py b/tests/test_processors.py new file mode 100644 index 00000000..316b57ff --- /dev/null +++ b/tests/test_processors.py @@ -0,0 +1,31 @@ +from imagekit.lib import Image +from imagekit.processors import ResizeToFill, ResizeToFit, SmartCrop +from nose.tools import eq_ +from .utils import create_image + + +def test_smartcrop(): + img = SmartCrop(100, 100).process(create_image()) + eq_(img.size, (100, 100)) + + +def test_resizetofill(): + img = ResizeToFill(100, 100).process(create_image()) + eq_(img.size, (100, 100)) + + +def test_resizetofit(): + # First create an image with aspect ratio 2:1... + img = Image.new('RGB', (200, 100)) + + # ...then resize it to fit within a 100x100 canvas. + img = ResizeToFit(100, 100).process(img) + + # Assert that the image has maintained the aspect ratio. + eq_(img.size, (100, 50)) + + +def test_resizetofit_mat(): + img = Image.new('RGB', (200, 100)) + img = ResizeToFit(100, 100, mat_color=0x000000).process(img) + eq_(img.size, (100, 100)) diff --git a/tests/utils.py b/tests/utils.py index 4acc13cb..746920fa 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,5 +1,4 @@ import os -import tempfile from django.core.files.base import ContentFile @@ -8,7 +7,7 @@ import pickle -def generate_lenna(): +def get_image_file(): """ See also: @@ -16,17 +15,20 @@ def generate_lenna(): http://sipi.usc.edu/database/database.php?volume=misc&image=12 """ - tmp = tempfile.TemporaryFile() - lennapath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', 'lenna-800x600-white-border.jpg') - with open(lennapath, "r+b") as lennafile: - Image.open(lennafile).save(tmp, 'JPEG') + path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', 'lenna-800x600-white-border.jpg') + tmp = StringIO() + tmp.write(open(path, 'r+b').read()) tmp.seek(0) return tmp +def create_image(): + return Image.open(get_image_file()) + + def create_instance(model_class, image_name): instance = model_class() - img = generate_lenna() + img = get_image_file() file = ContentFile(img.read()) instance.original_image = file instance.original_image.save(image_name, file) From c752eea6a0b60955d13a042eb4124ed6d5d996a8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 22:22:34 -0500 Subject: [PATCH 104/527] Fix bug with black mat_color --- imagekit/processors/resize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py index e4b747a9..5b211b33 100644 --- a/imagekit/processors/resize.py +++ b/imagekit/processors/resize.py @@ -215,6 +215,6 @@ def process(self, img): self.upscale: img = Resize(new_dimensions[0], new_dimensions[1]).process(img) - if self.mat_color: + if self.mat_color is not None: img = ResizeCanvas(self.width, self.height, self.mat_color, anchor=self.anchor).process(img) return img From c3f7aeca544191aebf324345c9fb7199b3bb39de Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 22:44:00 -0500 Subject: [PATCH 105/527] Separate serialization test --- tests/test_serialization.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/test_serialization.py diff --git a/tests/test_serialization.py b/tests/test_serialization.py new file mode 100644 index 00000000..76d53912 --- /dev/null +++ b/tests/test_serialization.py @@ -0,0 +1,13 @@ +""" +Make sure that the various IK classes can be successfully serialized and +deserialized. This is important when using IK with Celery. + +""" + +from .utils import create_photo, pickleback + + +def test_imagespecfield(): + instance = create_photo('pickletest2.jpg') + thumbnail = pickleback(instance.thumbnail) + thumbnail.source_file From 9d310ba57e5dca3d3fd87434b799a698d211739d Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 22:45:10 -0500 Subject: [PATCH 106/527] Remove old class-based tests --- tests/tests.py | 70 -------------------------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 tests/tests.py diff --git a/tests/tests.py b/tests/tests.py deleted file mode 100644 index 9dab0c8b..00000000 --- a/tests/tests.py +++ /dev/null @@ -1,70 +0,0 @@ -from __future__ import with_statement - -import os - -from django.test import TestCase - -from .models import (Photo, AbstractImageModel, ConcreteImageModel1, - ConcreteImageModel2) -from .utils import create_photo, pickleback - - -class IKTest(TestCase): - - def setUp(self): - self.photo = create_photo('test.jpg') - - def test_nodelete(self): - """Don't delete the spec file when the source image hasn't changed. - - """ - filename = self.photo.thumbnail.file.name - self.photo.save() - self.assertTrue(self.photo.thumbnail.storage.exists(filename)) - - def test_save_image(self): - photo = Photo.objects.get(id=self.photo.id) - self.assertTrue(os.path.isfile(photo.original_image.path)) - - def test_setup(self): - self.assertEqual(self.photo.original_image.width, 800) - self.assertEqual(self.photo.original_image.height, 600) - - def test_thumbnail_creation(self): - photo = Photo.objects.get(id=self.photo.id) - self.assertTrue(os.path.isfile(photo.thumbnail.file.name)) - - def test_thumbnail_size(self): - """ Explicit and smart-cropped thumbnail size """ - self.assertEqual(self.photo.thumbnail.width, 50) - self.assertEqual(self.photo.thumbnail.height, 50) - self.assertEqual(self.photo.smartcropped_thumbnail.width, 50) - self.assertEqual(self.photo.smartcropped_thumbnail.height, 50) - - def test_thumbnail_source_file(self): - self.assertEqual( - self.photo.thumbnail.source_file, self.photo.original_image) - - -class PickleTest(TestCase): - def test_model(self): - ph = pickleback(create_photo('pickletest.jpg')) - - # This isn't supposed to error. - ph.thumbnail.source_file - - def test_field(self): - thumbnail = pickleback(create_photo('pickletest2.jpg').thumbnail) - - # This isn't supposed to error. - thumbnail.source_file - - -class InheritanceTest(TestCase): - def test_abstract_base(self): - self.assertEqual(set(AbstractImageModel._ik.spec_fields), - set(['abstract_class_spec'])) - self.assertEqual(set(ConcreteImageModel1._ik.spec_fields), - set(['abstract_class_spec', 'first_spec'])) - self.assertEqual(set(ConcreteImageModel2._ik.spec_fields), - set(['abstract_class_spec', 'second_spec'])) From aaa823afd6772ac59414a95b79613c02220fac36 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 5 Nov 2012 23:34:32 -0500 Subject: [PATCH 107/527] Add flake8 linting --- Makefile | 1 + imagekit/__init__.py | 2 ++ imagekit/admin.py | 2 +- imagekit/forms/__init__.py | 2 ++ imagekit/imagecache/actions.py | 2 +- imagekit/imagecache/strategies.py | 1 - imagekit/lib.py | 2 ++ imagekit/management/commands/warmimagecache.py | 1 - imagekit/models/__init__.py | 2 ++ imagekit/models/fields/__init__.py | 10 +++++----- imagekit/models/fields/utils.py | 12 ++++++------ imagekit/processors/__init__.py | 2 ++ imagekit/processors/crop.py | 2 +- imagekit/processors/resize.py | 7 ++----- imagekit/templatetags/imagekit.py | 2 +- 15 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 65cd5913..3ec6c464 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ test: + flake8 --ignore=E501,E126,E127,E128 imagekit tests export PYTHONPATH=$(PWD):$(PYTHONPATH); \ django-admin.py test --settings=tests.settings tests diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 74808d32..747ce27c 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,3 +1,5 @@ +# flake8: noqa + from . import conf from .specs import ImageSpec from .pkgmeta import * diff --git a/imagekit/admin.py b/imagekit/admin.py index 4466e6ec..7a9e1454 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -27,7 +27,7 @@ def __call__(self, obj): try: thumbnail = getattr(obj, self.image_field) except AttributeError: - raise Exception('The property %s is not defined on %s.' % \ + raise Exception('The property %s is not defined on %s.' % (self.image_field, obj.__class__.__name__)) original_image = getattr(thumbnail, 'source_file', None) or thumbnail diff --git a/imagekit/forms/__init__.py b/imagekit/forms/__init__.py index 8086e947..f7310d18 100644 --- a/imagekit/forms/__init__.py +++ b/imagekit/forms/__init__.py @@ -1 +1,3 @@ +# flake8: noqa + from .fields import ProcessedImageField diff --git a/imagekit/imagecache/actions.py b/imagekit/imagecache/actions.py index 2e222b3e..b829a5fb 100644 --- a/imagekit/imagecache/actions.py +++ b/imagekit/imagecache/actions.py @@ -12,7 +12,7 @@ def validate_now(file): def deferred_validate(file): try: - import celery + import celery # NOQA except: raise ImportError("Deferred validation requires the the 'celery' library") validate_now_task.delay(file) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index 3eca7473..630b77cb 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -54,6 +54,5 @@ def invoke_callback(self, name, *args, **kwargs): def __unicode__(self): return unicode(self._wrapped) - def __str__(self): return str(self._wrapped) diff --git a/imagekit/lib.py b/imagekit/lib.py index 574e5874..7137e08a 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,3 +1,5 @@ +# flake8: noqa + # Required PIL classes may or may not be available from the root namespace # depending on the installation method used. try: diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 8c9efcbb..8c25aaab 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -1,4 +1,3 @@ -from optparse import make_option from django.core.management.base import BaseCommand import re from ...files import ImageSpecCacheFile diff --git a/imagekit/models/__init__.py b/imagekit/models/__init__.py index 4c3dad75..b13b38f9 100644 --- a/imagekit/models/__init__.py +++ b/imagekit/models/__init__.py @@ -1,2 +1,4 @@ +# flake8: noqa + from .. import conf from .fields import ImageSpecField, ProcessedImageField diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 3f98f352..d7e4d8af 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -26,9 +26,9 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, - image_field=None, storage=None, autoconvert=None, - image_cache_backend=None, image_cache_strategy=None, spec=None, - id=None): + image_field=None, storage=None, autoconvert=None, + image_cache_backend=None, image_cache_strategy=None, spec=None, + id=None): SpecHost.__init__(self, processors=processors, format=format, options=options, storage=storage, autoconvert=autoconvert, @@ -58,8 +58,8 @@ class ProcessedImageField(models.ImageField, SpecHostField): attr_class = ProcessedImageFieldFile def __init__(self, processors=None, format=None, options=None, - verbose_name=None, name=None, width_field=None, height_field=None, - autoconvert=True, spec=None, spec_id=None, **kwargs): + verbose_name=None, name=None, width_field=None, height_field=None, + autoconvert=True, spec=None, spec_id=None, **kwargs): """ The ProcessedImageField constructor accepts all of the arguments that the :class:`django.db.models.ImageField` constructor accepts, as well diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 0695212c..30430165 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -15,16 +15,16 @@ def __get__(self, instance, owner): if field_name: source_file = getattr(instance, field_name) else: - image_fields = [getattr(instance, f.attname) for f in \ - instance.__class__._meta.fields if \ + image_fields = [getattr(instance, f.attname) for f in + instance.__class__._meta.fields if isinstance(f, ImageField)] if len(image_fields) == 0: - raise Exception('%s does not define any ImageFields, so your' \ - ' %s ImageSpecField has no image to act on.' % \ + raise Exception('%s does not define any ImageFields, so your' + ' %s ImageSpecField has no image to act on.' % (instance.__class__.__name__, self.attname)) elif len(image_fields) > 1: - raise Exception('%s defines multiple ImageFields, but you' \ - ' have not specified an image_field for your %s' \ + raise Exception('%s defines multiple ImageFields, but you' + ' have not specified an image_field for your %s' ' ImageSpecField.' % (instance.__class__.__name__, self.attname)) else: diff --git a/imagekit/processors/__init__.py b/imagekit/processors/__init__.py index c2c93200..6c8d0b7b 100644 --- a/imagekit/processors/__init__.py +++ b/imagekit/processors/__init__.py @@ -1,3 +1,5 @@ +# flake8: noqa + """ Imagekit image processors. diff --git a/imagekit/processors/crop.py b/imagekit/processors/crop.py index da5c0fb0..b039d302 100644 --- a/imagekit/processors/crop.py +++ b/imagekit/processors/crop.py @@ -1,4 +1,4 @@ -from .base import Anchor +from .base import Anchor # noqa from .utils import histogram_entropy from ..lib import Image, ImageChops, ImageDraw, ImageStat diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py index 5b211b33..fea3d51d 100644 --- a/imagekit/processors/resize.py +++ b/imagekit/processors/resize.py @@ -1,5 +1,4 @@ from imagekit.lib import Image -import warnings from .base import Anchor @@ -211,10 +210,8 @@ def process(self, img): ratio = float(self.width) / cur_width new_dimensions = (int(round(cur_width * ratio)), int(round(cur_height * ratio))) - if (cur_width > new_dimensions[0] or cur_height > new_dimensions[1]) or \ - self.upscale: - img = Resize(new_dimensions[0], - new_dimensions[1]).process(img) + if (cur_width > new_dimensions[0] or cur_height > new_dimensions[1]) or self.upscale: + img = Resize(new_dimensions[0], new_dimensions[1]).process(img) if self.mat_color is not None: img = ResizeCanvas(self.width, self.height, self.mat_color, anchor=self.anchor).process(img) return img diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index b0b981bf..ade02d8a 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -110,7 +110,7 @@ def spec(parser, token): """ bits = token.split_contents() - tag_name = bits.pop(0) + tag_name = bits.pop(0) # noqa if len(bits) == 4 and bits[2] == 'as': return SpecResultAssignmentNode( From 7532e5040bd9487ddc4d74dcac22209b2fee33de Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 6 Nov 2012 00:40:14 -0500 Subject: [PATCH 108/527] Add contributing guidelines --- CONTRIBUTING.rst | 24 ++++++++++++++++++++++++ README.rst | 10 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 CONTRIBUTING.rst diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 00000000..875ec2cb --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,24 @@ +Contributing +------------ + +We love contributions! These guidelines will help make sure we can get your +contributions merged as quickly as possible: + +1. Write `good commit messages`__! +2. If you want to add a new feature, talk to us on the `mailing list`__ or + `IRC`__ first. We might already have plans, or be able to offer some advice. +3. Make sure your code passes the tests that ImageKit already has. To run the + tests, use ``make test``. This will let you know about any errors or style + issues. +4. While we're talking about tests, creating new ones for your code makes it + much easier for us to merge your code quickly. ImageKit uses nose_, so + writing tests is painless. Check out `ours`__ for examples. +5. It's a good idea to do your work in a branch; that way, you can work on more + than one contribution at a time without making them interdependent. + + +__ http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +__ https://groups.google.com/forum/#!forum/django-imagekit +__ irc://irc.freenode.net/imagekit +.. _nose: https://nose.readthedocs.org/en/latest/ +__ https://github.com/jdriscoll/django-imagekit/tree/develop/tests diff --git a/README.rst b/README.rst index 242562ab..1eea9126 100644 --- a/README.rst +++ b/README.rst @@ -295,3 +295,13 @@ even Django—to contribute either: ImageKit's processors are standalone classes that are completely separate from the more intimidating internals of Django's ORM. If you've written a processor that you think might be useful to other people, open a pull request so we can take a look! + +You can also check out our list of `open, contributor-friendly issues`__ for +ideas. + +Check out our `contributing guidelines`__ for more information about pitching in +with ImageKit. + + +__ https://github.com/jdriscoll/django-imagekit/issues?labels=contributor-friendly&state=open +__ https://github.com/jdriscoll/django-imagekit/blob/master/CONTRIBUTING.rst From 5a414a3644006440e82d03b03057b39dc5e70037 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 6 Nov 2012 23:50:23 -0500 Subject: [PATCH 109/527] Rename spec_args to spec_attrs --- imagekit/specs/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index ae1ba65b..94810d08 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -233,14 +233,14 @@ class SpecHost(object): """ def __init__(self, spec=None, spec_id=None, **kwargs): - spec_args = dict((k, v) for k, v in kwargs.items() if v is not None) + spec_attrs = dict((k, v) for k, v in kwargs.items() if v is not None) - if spec_args: + if spec_attrs: if spec: raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - spec = type('Spec', (ImageSpec,), spec_args) # TODO: Base class name on spec id? + spec = type('Spec', (ImageSpec,), spec_attrs) # TODO: Base class name on spec id? self._original_spec = spec From 49a55d4763994dce12ddc7aab6e9d744e9432eb4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 14:11:04 -0500 Subject: [PATCH 110/527] Try adding __reduce__ --- imagekit/specs/__init__.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 94810d08..6791aefd 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -225,6 +225,17 @@ def generate(self, source_file, filename=None): return content +class DynamicSpec(ImageSpec): + def __reduce__(self): + return (create_spec_class, (self._spec_attrs,)) + + +def create_spec_class(spec_attrs): + cls = type('Spec', (DynamicSpec,), spec_attrs) + cls._spec_attrs = spec_attrs + return cls + + class SpecHost(object): """ An object that ostensibly has a spec attribute but really delegates to the @@ -240,7 +251,8 @@ def __init__(self, spec=None, spec_id=None, **kwargs): raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - spec = type('Spec', (ImageSpec,), spec_attrs) # TODO: Base class name on spec id? + # spec = type('Spec', (ImageSpec,), spec_attrs) # TODO: Base class name on spec id? + spec = create_spec_class(spec_attrs) self._original_spec = spec From 5b1c5f7b4e505bfff0a5c834715881055700bb4a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 15:51:28 -0500 Subject: [PATCH 111/527] Rename source objects to source groups --- imagekit/models/fields/__init__.py | 4 ++-- imagekit/specs/__init__.py | 2 +- imagekit/specs/{sources.py => sourcegroups.py} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename imagekit/specs/{sources.py => sourcegroups.py} (98%) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index d7e4d8af..153e7937 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -3,7 +3,7 @@ from .utils import ImageSpecFileDescriptor from ... import specs from ...specs import SpecHost -from ...specs.sources import ImageFieldSpecSource +from ...specs.sourcegroups import ImageFieldSourceGroup class SpecHostField(SpecHost): @@ -44,7 +44,7 @@ def contribute_to_class(self, cls, name): # Add the model and field as a source for this spec id specs.registry.add_sources(self.spec_id, - [ImageFieldSpecSource(cls, self.image_field)]) + [ImageFieldSourceGroup(cls, self.image_field)]) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 6791aefd..7d5c0fcf 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -53,7 +53,7 @@ def register(self, spec, id=None): raise AlreadyRegistered('The spec with id %s is already registered' % id) self._specs[id] = spec - sources = getattr(config, 'sources', None) or [] + sources = getattr(config, 'source_groups', None) or [] self.add_sources(id, sources) def unregister(self, id, spec): diff --git a/imagekit/specs/sources.py b/imagekit/specs/sourcegroups.py similarity index 98% rename from imagekit/specs/sources.py rename to imagekit/specs/sourcegroups.py index 3be4a7e8..551d8598 100644 --- a/imagekit/specs/sources.py +++ b/imagekit/specs/sourcegroups.py @@ -6,7 +6,7 @@ def ik_model_receiver(fn): """ A method decorator that filters out signals coming from models that don't - have fields that function as ImageFieldSpecSources + have fields that function as ImageFieldSourceGroup """ @wraps(fn) @@ -97,7 +97,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): signal.send(sender=source, source_file=file, info=info) -class ImageFieldSpecSource(object): +class ImageFieldSourceGroup(object): def __init__(self, model_class, image_field): """ Good design would dictate that this instance would be responsible for From 4ead0b3002fd42f0d66e95a210081cc90278a50a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 15:51:40 -0500 Subject: [PATCH 112/527] Add note about nested config classes --- imagekit/specs/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 7d5c0fcf..63615499 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -38,6 +38,7 @@ def __init__(self): before_access.connect(self.before_access_receiver) def register(self, spec, id=None): + # TODO: Should we really allow a nested Config class, since it's not necessarily associated with its container? config = getattr(spec, 'Config', None) if id is None: From 54baa4490015a10b4b89d65b1f02272a08a61b58 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 15:56:37 -0500 Subject: [PATCH 113/527] Require spec id for form fields Closes #163 --- imagekit/forms/fields.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index 19a43873..40bb5b52 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -5,10 +5,13 @@ class ProcessedImageField(ImageField, SpecHost): def __init__(self, processors=None, format=None, options=None, - autoconvert=True, spec=None, spec_id=None, *args, **kwargs): + autoconvert=True, spec_id=None, spec=None, *args, **kwargs): if spec_id is None: - spec_id = '??????' # FIXME: Wher should we get this? + # Unlike model fields, form fields are never told their field name. + # (Model fields are done so via `contribute_to_class()`.) Therefore + # we can't really generate a good spec id automatically. + raise TypeError('You must provide a spec_id') SpecHost.__init__(self, processors=processors, format=format, options=options, autoconvert=autoconvert, spec=spec, From d253fe281ad55620e116f2cce9c7262e613de7a7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 16:46:10 -0500 Subject: [PATCH 114/527] Rename `image_field` argument; closes #158 --- README.rst | 4 ++-- imagekit/models/fields/__init__.py | 7 ++++--- imagekit/models/fields/utils.py | 4 ++-- tests/models.py | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 1eea9126..db024c39 100644 --- a/README.rst +++ b/README.rst @@ -121,7 +121,7 @@ of applying a spec to another one of your model's fields: class Photo(models.Model): avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(id='myapp:fancy_thumbnail', image_field='avatar') + avatar_thumbnail = ImageSpecField(id='myapp:fancy_thumbnail', source='avatar') photo = Photo.objects.all()[0] print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg @@ -142,7 +142,7 @@ writing a subclass of ``ImageSpec``: avatar_thumbnail = ImageSpecField(processors=[ResizeToFill(100, 50)], format='JPEG', options={'quality': 60}, - image_field='avatar') + source='avatar') photo = Photo.objects.all()[0] print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 153e7937..95d5914d 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -26,7 +26,7 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, - image_field=None, storage=None, autoconvert=None, + source=None, storage=None, autoconvert=None, image_cache_backend=None, image_cache_strategy=None, spec=None, id=None): @@ -36,7 +36,8 @@ def __init__(self, processors=None, format=None, options=None, image_cache_strategy=image_cache_strategy, spec=spec, spec_id=id) - self.image_field = image_field + # TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664 + self.source = source def contribute_to_class(self, cls, name): setattr(cls, name, ImageSpecFileDescriptor(self, name)) @@ -44,7 +45,7 @@ def contribute_to_class(self, cls, name): # Add the model and field as a source for this spec id specs.registry.add_sources(self.spec_id, - [ImageFieldSourceGroup(cls, self.image_field)]) + [ImageFieldSourceGroup(cls, self.source)]) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 30430165..efba3035 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -11,7 +11,7 @@ def __get__(self, instance, owner): if instance is None: return self.field else: - field_name = getattr(self.field, 'image_field', None) + field_name = getattr(self.field, 'source', None) if field_name: source_file = getattr(instance, field_name) else: @@ -24,7 +24,7 @@ def __get__(self, instance, owner): (instance.__class__.__name__, self.attname)) elif len(image_fields) > 1: raise Exception('%s defines multiple ImageFields, but you' - ' have not specified an image_field for your %s' + ' have not specified a source for your %s' ' ImageSpecField.' % (instance.__class__.__name__, self.attname)) else: diff --git a/tests/models.py b/tests/models.py index 2c3d8e47..199fdc07 100644 --- a/tests/models.py +++ b/tests/models.py @@ -10,11 +10,11 @@ class Photo(models.Model): original_image = models.ImageField(upload_to='photos') thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1), - ResizeToFill(50, 50)], image_field='original_image', format='JPEG', + ResizeToFill(50, 50)], source='original_image', format='JPEG', options={'quality': 90}) smartcropped_thumbnail = ImageSpecField([Adjust(contrast=1.2, - sharpness=1.1), SmartCrop(50, 50)], image_field='original_image', + sharpness=1.1), SmartCrop(50, 50)], source='original_image', format='JPEG', options={'quality': 90}) From e0567e8fa726a616f52bef5b1eb5a6994dacb15a Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Sat, 1 Dec 2012 17:03:51 -0500 Subject: [PATCH 115/527] Remove specs.SpecRegistry; add registry module The registry module splits the work that specs.SpecRegistry used to do into two classes: GeneratorRegistry and SourceGroupRegistry. These two registries are wrapped in Register and Unregister utilities for API convenience. --- imagekit/__init__.py | 1 + imagekit/exceptions.py | 2 +- .../management/commands/warmimagecache.py | 8 +- imagekit/models/fields/__init__.py | 4 +- imagekit/registry.py | 156 ++++++++++++++++++ imagekit/specs/__init__.py | 116 +------------ imagekit/templatetags/imagekit.py | 4 +- 7 files changed, 170 insertions(+), 121 deletions(-) create mode 100644 imagekit/registry.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 747ce27c..2c72bf44 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -3,3 +3,4 @@ from . import conf from .specs import ImageSpec from .pkgmeta import * +from .registry import register, unregister diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index b453f16c..308c0a17 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -14,5 +14,5 @@ class UnknownFormatError(Exception): pass -class MissingSpecId(Exception): +class MissingGeneratorId(Exception): pass diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 8c25aaab..db8ebaab 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -1,7 +1,7 @@ from django.core.management.base import BaseCommand import re from ...files import ImageSpecCacheFile -from ...specs import registry +from ...registry import generator_registry, source_group_registry class Command(BaseCommand): @@ -11,7 +11,7 @@ class Command(BaseCommand): args = '[spec_ids]' def handle(self, *args, **options): - specs = registry.get_spec_ids() + specs = generator_registry.get_ids() if args: patterns = self.compile_patterns(args) @@ -19,8 +19,8 @@ def handle(self, *args, **options): for spec_id in specs: self.stdout.write('Validating spec: %s\n' % spec_id) - spec = registry.get_spec(spec_id) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) - for source in registry.get_sources(spec_id): + spec = generator_registry.get(spec_id) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) + for source in source_group_registry.get(spec_id): for source_file in source.files(): if source_file: self.stdout.write(' %s\n' % source_file) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 95d5914d..6b3287c0 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,9 +1,9 @@ from django.db import models from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor -from ... import specs from ...specs import SpecHost from ...specs.sourcegroups import ImageFieldSourceGroup +from ...registry import register class SpecHostField(SpecHost): @@ -44,7 +44,7 @@ def contribute_to_class(self, cls, name): self.set_spec_id(cls, name) # Add the model and field as a source for this spec id - specs.registry.add_sources(self.spec_id, + register.sources(self.spec_id, [ImageFieldSourceGroup(cls, self.source)]) diff --git a/imagekit/registry.py b/imagekit/registry.py new file mode 100644 index 00000000..5952b4eb --- /dev/null +++ b/imagekit/registry.py @@ -0,0 +1,156 @@ +from .exceptions import AlreadyRegistered, NotRegistered, MissingGeneratorId +from .signals import (before_access, source_created, source_changed, + source_deleted) + + +class GeneratorRegistry(object): + """ + An object for registering generators (specs). This registry provides + a convenient way for a distributable app to define default generators + without locking the users of the app into it. + + """ + def __init__(self): + self._generators = {} + + def register(self, generator, id=None): + # TODO: Should we really allow a nested Config class, since it's not necessarily associated with its container? + config = getattr(generator, 'Config', None) + + if id is None: + id = getattr(config, 'id', None) + + if id is None: + raise MissingGeneratorId('No id provided for %s. You must either' + ' pass an id to the register function, or add' + ' an id attribute to the inner Config class of' + ' your spec or generator.' % generator) + + if id in self._generators: + raise AlreadyRegistered('The spec or generator with id %s is' + ' already registered' % id) + self._generators[id] = generator + + source_groups = getattr(config, 'source_groups', None) or [] + source_group_registry.register(id, source_groups) + + def unregister(self, id, generator): + try: + del self._generators[id] + except KeyError: + raise NotRegistered('The spec or generator with id %s is not' + ' registered' % id) + + def get(self, id, **kwargs): + try: + generator = self._generators[id] + except KeyError: + raise NotRegistered('The spec or generator with id %s is not' + ' registered' % id) + if callable(generator): + return generator(**kwargs) + else: + return generator + + def get_ids(self): + return self._generators.keys() + + +class SourceGroupRegistry(object): + """ + An object for registering source groups with specs. The two are + associated with each other via a string id. We do this (as opposed to + associating them directly by, for example, putting a ``source_groups`` + attribute on specs) so that specs can be overridden without losing the + associated sources. That way, a distributable app can define its own + specs without locking the users of the app into it. + + """ + + _source_signals = [ + source_created, + source_changed, + source_deleted, + ] + + def __init__(self): + self._sources = {} + for signal in self._source_signals: + signal.connect(self.source_receiver) + before_access.connect(self.before_access_receiver) + + def register(self, spec_id, sources): + """ + Associates sources with a spec id + + """ + for source in sources: + if source not in self._sources: + self._sources[source] = set() + self._sources[source].add(spec_id) + + def unregister(self, spec_id, sources): + """ + Disassociates sources with a spec id + + """ + for source in sources: + try: + self._sources[source].remove(spec_id) + except KeyError: + continue + + def get(self, spec_id): + return [source for source in self._sources + if spec_id in self._sources[source]] + + def before_access_receiver(self, sender, generator, file, **kwargs): + generator.image_cache_strategy.invoke_callback('before_access', file) + + def source_receiver(self, sender, source_file, signal, info, **kwargs): + """ + Redirects signals dispatched on sources to the appropriate specs. + + """ + source = sender + if source not in self._sources: + return + + for spec in (generator_registry.get(id, source_file=source_file, **info) + for id in self._sources[source]): + event_name = { + source_created: 'source_created', + source_changed: 'source_changed', + source_deleted: 'source_deleted', + } + spec._handle_source_event(event_name, source_file) + + +class Register(object): + """ + Register specs and sources. + + """ + def spec(self, id, spec): + generator_registry.register(id, spec) + + def sources(self, spec_id, sources): + source_group_registry.register(spec_id, sources) + + +class Unregister(object): + """ + Unregister specs and sources. + + """ + def spec(self, id, spec): + generator_registry.unregister(id, spec) + + def sources(self, spec_id, sources): + source_group_registry.unregister(spec_id, sources) + + +generator_registry = GeneratorRegistry() +source_group_registry = SourceGroupRegistry() +register = Register() +unregister = Unregister() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 63615499..2f416763 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -2,113 +2,13 @@ from hashlib import md5 import os import pickle -from ..exceptions import (UnknownExtensionError, AlreadyRegistered, - NotRegistered, MissingSpecId) +from ..exceptions import UnknownExtensionError from ..files import ImageSpecCacheFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..processors import ProcessorPipeline -from ..signals import (before_access, source_created, source_changed, - source_deleted) from ..utils import open_image, extension_to_format, img_to_fobj - - -class SpecRegistry(object): - """ - An object for registering specs and sources. The two are associated with - eachother via a string id. We do this (as opposed to associating them - directly by, for example, putting a ``sources`` attribute on specs) so that - specs can be overridden without losing the associated sources. That way, - a distributable app can define its own specs without locking the users of - the app into it. - - """ - - _source_signals = [ - source_created, - source_changed, - source_deleted, - ] - - def __init__(self): - self._specs = {} - self._sources = {} - for signal in self._source_signals: - signal.connect(self.source_receiver) - before_access.connect(self.before_access_receiver) - - def register(self, spec, id=None): - # TODO: Should we really allow a nested Config class, since it's not necessarily associated with its container? - config = getattr(spec, 'Config', None) - - if id is None: - id = getattr(config, 'id', None) - - if id is None: - raise MissingSpecId('No id provided for %s. You must either pass an' - ' id to the register function, or add an id' - ' attribute to the inner Config class of your' - ' spec.' % spec) - - if id in self._specs: - raise AlreadyRegistered('The spec with id %s is already registered' % id) - self._specs[id] = spec - - sources = getattr(config, 'source_groups', None) or [] - self.add_sources(id, sources) - - def unregister(self, id, spec): - try: - del self._specs[id] - except KeyError: - raise NotRegistered('The spec with id %s is not registered' % id) - - def get_spec(self, id, **kwargs): - try: - spec = self._specs[id] - except KeyError: - raise NotRegistered('The spec with id %s is not registered' % id) - if callable(spec): - return spec(**kwargs) - else: - return spec - - def get_spec_ids(self): - return self._specs.keys() - - def add_sources(self, spec_id, sources): - """ - Associates sources with a spec id - - """ - for source in sources: - if source not in self._sources: - self._sources[source] = set() - self._sources[source].add(spec_id) - - def get_sources(self, spec_id): - return [source for source in self._sources if spec_id in self._sources[source]] - - def before_access_receiver(self, sender, generator, file, **kwargs): - generator.image_cache_strategy.invoke_callback('before_access', file) - - def source_receiver(self, sender, source_file, signal, info, **kwargs): - """ - Redirects signals dispatched on sources to the appropriate specs. - - """ - source = sender - if source not in self._sources: - return - - for spec in (self.get_spec(id, source_file=source_file, **info) - for id in self._sources[source]): - event_name = { - source_created: 'source_created', - source_changed: 'source_changed', - source_deleted: 'source_deleted', - } - spec._handle_source_event(event_name, source_file) +from ..registry import generator_registry, register class BaseImageSpec(object): @@ -270,7 +170,7 @@ def set_spec_id(self, id): """ self.spec_id = id - registry.register(self._original_spec, id) + register.spec(self._original_spec, id) def get_spec(self, **kwargs): """ @@ -282,12 +182,4 @@ def get_spec(self, **kwargs): """ if not getattr(self, 'spec_id', None): raise Exception('Object %s has no spec id.' % self) - return registry.get_spec(self.spec_id, **kwargs) - - -registry = SpecRegistry() -register = registry.register - - -def unregister(id, spec): - registry.unregister(id, spec) + return generator_registry.get(self.spec_id, **kwargs) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index ade02d8a..eea4f8c8 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -2,7 +2,7 @@ from django.utils.safestring import mark_safe import re from ..files import ImageSpecCacheFile -from .. import specs +from ..registry import generator_registry register = template.Library() @@ -34,7 +34,7 @@ def get_spec(self, context): from ..utils import autodiscover autodiscover() spec_id = self._spec_id.resolve(context) - spec = specs.registry.get_spec(spec_id) # TODO: What "hints" here? + spec = generator_registry.get(spec_id) # TODO: What "hints" here? return spec def get_source_file(self, context): From 9188499965e37a38826d8b203e90ac3a0130ec68 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 20:36:31 -0500 Subject: [PATCH 116/527] Rework template tag for generators --- imagekit/conf.py | 2 +- imagekit/files.py | 2 +- imagekit/registry.py | 2 +- imagekit/templatetags/compat.py | 160 +++++++++++++++++++++++++++++ imagekit/templatetags/imagekit.py | 163 ++++++++++-------------------- imagekit/utils.py | 2 +- 6 files changed, 218 insertions(+), 113 deletions(-) create mode 100644 imagekit/templatetags/compat.py diff --git a/imagekit/conf.py b/imagekit/conf.py index ed568db1..288d3668 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -8,7 +8,7 @@ class ImageKitConf(AppConf): CACHE_DIR = 'CACHE/images' CACHE_PREFIX = 'imagekit:' DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.JustInTime' - DEFAULT_FILE_STORAGE = None # Indicates that the source storage should be used + DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' def configure_cache_backend(self, value): if value is None: diff --git a/imagekit/files.py b/imagekit/files.py index fddcce22..d92389a7 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -95,7 +95,7 @@ def __init__(self, generator, name=None, *args, **kwargs): self.args = args self.kwargs = kwargs storage = getattr(generator, 'storage', None) - if not storage and settings.IMAGEKIT_DEFAULT_FILE_STORAGE: + if not storage: storage = get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') super(GeneratedImageCacheFile, self).__init__(storage=storage) diff --git a/imagekit/registry.py b/imagekit/registry.py index 5952b4eb..4147f877 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -132,7 +132,7 @@ class Register(object): """ def spec(self, id, spec): - generator_registry.register(id, spec) + generator_registry.register(spec, id) def sources(self, spec_id, sources): source_group_registry.register(spec_id, sources) diff --git a/imagekit/templatetags/compat.py b/imagekit/templatetags/compat.py new file mode 100644 index 00000000..8334dec2 --- /dev/null +++ b/imagekit/templatetags/compat.py @@ -0,0 +1,160 @@ +""" +This module contains code from django.template.base +(sha 90d3af380e8efec0301dd91600c6686232de3943). Bundling this code allows us to +support older versions of Django that did not contain it (< 1.4). + + +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Django nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" + +from django.template import TemplateSyntaxError +import re + + +# Regex for token keyword arguments +kwarg_re = re.compile(r"(?:(\w+)=)?(.+)") + + +def token_kwargs(bits, parser, support_legacy=False): + """ + A utility method for parsing token keyword arguments. + + :param bits: A list containing remainder of the token (split by spaces) + that is to be checked for arguments. Valid arguments will be removed + from this list. + + :param support_legacy: If set to true ``True``, the legacy format + ``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1`` + format is allowed. + + :returns: A dictionary of the arguments retrieved from the ``bits`` token + list. + + There is no requirement for all remaining token ``bits`` to be keyword + arguments, so the dictionary will be returned as soon as an invalid + argument format is reached. + """ + if not bits: + return {} + match = kwarg_re.match(bits[0]) + kwarg_format = match and match.group(1) + if not kwarg_format: + if not support_legacy: + return {} + if len(bits) < 3 or bits[1] != 'as': + return {} + + kwargs = {} + while bits: + if kwarg_format: + match = kwarg_re.match(bits[0]) + if not match or not match.group(1): + return kwargs + key, value = match.groups() + del bits[:1] + else: + if len(bits) < 3 or bits[1] != 'as': + return kwargs + key, value = bits[2], bits[0] + del bits[:3] + kwargs[key] = parser.compile_filter(value) + if bits and not kwarg_format: + if bits[0] != 'and': + return kwargs + del bits[:1] + return kwargs + + +def parse_bits(parser, bits, params, varargs, varkw, defaults, + takes_context, name): + """ + Parses bits for template tag helpers (simple_tag, include_tag and + assignment_tag), in particular by detecting syntax errors and by + extracting positional and keyword arguments. + """ + if takes_context: + if params[0] == 'context': + params = params[1:] + else: + raise TemplateSyntaxError( + "'%s' is decorated with takes_context=True so it must " + "have a first argument of 'context'" % name) + args = [] + kwargs = {} + unhandled_params = list(params) + for bit in bits: + # First we try to extract a potential kwarg from the bit + kwarg = token_kwargs([bit], parser) + if kwarg: + # The kwarg was successfully extracted + param, value = list(kwarg.items())[0] + if param not in params and varkw is None: + # An unexpected keyword argument was supplied + raise TemplateSyntaxError( + "'%s' received unexpected keyword argument '%s'" % + (name, param)) + elif param in kwargs: + # The keyword argument has already been supplied once + raise TemplateSyntaxError( + "'%s' received multiple values for keyword argument '%s'" % + (name, param)) + else: + # All good, record the keyword argument + kwargs[str(param)] = value + if param in unhandled_params: + # If using the keyword syntax for a positional arg, then + # consume it. + unhandled_params.remove(param) + else: + if kwargs: + raise TemplateSyntaxError( + "'%s' received some positional argument(s) after some " + "keyword argument(s)" % name) + else: + # Record the positional argument + args.append(parser.compile_filter(bit)) + try: + # Consume from the list of expected positional arguments + unhandled_params.pop(0) + except IndexError: + if varargs is None: + raise TemplateSyntaxError( + "'%s' received too many positional arguments" % + name) + if defaults is not None: + # Consider the last n params handled, where n is the + # number of defaults. + unhandled_params = unhandled_params[:-len(defaults)] + if unhandled_params: + # Some positional arguments were not supplied + raise TemplateSyntaxError( + "'%s' did not receive value(s) for the argument(s): %s" % + (name, ", ".join(["'%s'" % p for p in unhandled_params]))) + return args, kwargs diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index eea4f8c8..f114a808 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,134 +1,79 @@ from django import template -from django.utils.safestring import mark_safe -import re -from ..files import ImageSpecCacheFile +from .compat import parse_bits +from ..files import GeneratedImageCacheFile from ..registry import generator_registry register = template.Library() -html_attr_pattern = r""" - (?P\w+) # The attribute name - ( - \s*=\s* # an equals sign, that may or may not have spaces around it - (?P - ("[^"]*") # a double-quoted value - | # or - ('[^']*') # a single-quoted value - | # or - ([^"'<>=\s]+) # an unquoted value - ) - )? -""" +class GenerateImageAssignmentNode(template.Node): + _kwarg_map = { + 'from': 'source_file', + } -html_attr_re = re.compile(html_attr_pattern, re.VERBOSE) - - -class SpecResultNodeMixin(object): - def __init__(self, spec_id, source_file): - self._spec_id = spec_id - self._source_file = source_file - - def get_spec(self, context): - from ..utils import autodiscover - autodiscover() - spec_id = self._spec_id.resolve(context) - spec = generator_registry.get(spec_id) # TODO: What "hints" here? - return spec - - def get_source_file(self, context): - return self._source_file.resolve(context) - - def get_file(self, context): - spec = self.get_spec(context) - source_file = self.get_source_file(context) - return ImageSpecCacheFile(spec, source_file) - - -class SpecResultAssignmentNode(template.Node, SpecResultNodeMixin): - def __init__(self, spec_id, source_file, variable_name): - super(SpecResultAssignmentNode, self).__init__(spec_id, source_file) + def __init__(self, variable_name, generator_id, **kwargs): + self.generator_id = generator_id + self.kwargs = kwargs self._variable_name = variable_name def get_variable_name(self, context): return unicode(self._variable_name) + def get_kwargs(self, context): + return dict((self._kwarg_map.get(k, k), v.resolve(context)) for k, + v in self.kwargs.items()) + def render(self, context): + from ..utils import autodiscover + autodiscover() + variable_name = self.get_variable_name(context) - context[variable_name] = self.get_file(context) + generator_id = self.generator_id.resolve(context) + kwargs = self.get_kwargs(context) + generator = generator_registry.get(generator_id) + context[variable_name] = GeneratedImageCacheFile(generator, **kwargs) return '' -class SpecResultImgTagNode(template.Node, SpecResultNodeMixin): - def __init__(self, spec_id, source_file, html_attrs): - super(SpecResultImgTagNode, self).__init__(spec_id, source_file) - self._html_attrs = html_attrs - - def get_html_attrs(self, context): - attrs = [] - for attr in self._html_attrs: - match = html_attr_re.search(attr) - if match: - attrs.append((match.group('name'), match.group('value'))) - return attrs - - def get_attr_str(self, k, v): - return k if v is None else '%s=%s' % (k, v) - - def render(self, context): - file = self.get_file(context) - attrs = self.get_html_attrs(context) - attr_dict = dict(attrs) - if not 'width' in attr_dict and not 'height' in attr_dict: - attrs = attrs + [('width', '"%s"' % file.width), - ('height', '"%s"' % file.height)] - attrs = [('src', '"%s"' % file.url)] + attrs - attr_str = ' '.join(self.get_attr_str(k, v) for k, v in attrs) - return mark_safe(u'' % attr_str) - - #@register.tag -# TODO: Should this be renamed to something like 'process'? -def spec(parser, token): +def generateimage(parser, token): """ - Creates an image based on the provided spec and source image. - - By default:: - - {% spec 'myapp:thumbnail' mymodel.profile_image %} - - Generates an ````:: - - - - Storing it as a context variable allows more flexibility:: - - {% spec 'myapp:thumbnail' mymodel.profile_image as th %} - + Creates an image based on the provided arguments. """ bits = token.split_contents() - tag_name = bits.pop(0) # noqa - - if len(bits) == 4 and bits[2] == 'as': - return SpecResultAssignmentNode( - parser.compile_filter(bits[0]), # spec id - parser.compile_filter(bits[1]), # source file - parser.compile_filter(bits[3]), # var name - ) - elif len(bits) > 1: - return SpecResultImgTagNode( - parser.compile_filter(bits[0]), # spec id - parser.compile_filter(bits[1]), # source file - bits[2:], # html attributes - ) + tag_name = bits.pop(0) + + if bits[-2] == 'as': + varname = bits[-1] + bits = bits[:-2] + + # (params, varargs, varkwargs, defaults) = getargspec(g) + # (params, 'args', 'kwargs', defaults) = getargspec(g) + + args, kwargs = parse_bits(parser, bits, + ['generator_id'], 'args', 'kwargs', None, + False, tag_name) + if len(args) != 1: + raise template.TemplateSyntaxError("The 'generateimage' tag " + ' requires exactly one unnamed argument.') + generator_id = args[0] + return GenerateImageAssignmentNode(varname, generator_id, **kwargs) else: - raise template.TemplateSyntaxError('\'spec\' tags must be in the form' - ' "{% spec spec_id image %}" or' - ' "{% spec spec_id image' - ' as varname %}"') - - -spec = spec_tag = register.tag(spec) + raise Exception('!!') + # elif len(bits) > 1: + # return GenerateImageTagNode( + # parser.compile_filter(bits[0]), # spec id + # parser.compile_filter(bits[1]), # source file + # bits[2:], # html attributes + # ) + # else: + # raise template.TemplateSyntaxError('\'generateimage\' tags must be in the form' + # ' "{% generateimage id image %}" or' + # ' "{% generateimage id image' + # ' as varname %}"') + + +generateimage = register.tag(generateimage) diff --git a/imagekit/utils.py b/imagekit/utils.py index 7495238e..ac93cf64 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -371,7 +371,7 @@ def autodiscover(): import_module('%s.imagespecs' % app) except: # Decide whether to bubble up this error. If the app just - # doesn't have an admin module, we can ignore the error + # doesn't have an imagespecs module, we can ignore the error # attempting to import it, otherwise we want it to bubble up. if module_has_submodule(mod, 'imagespecs'): raise From 1f06c9ac700b6bdbd816da4fe81b05bb135dc9c0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 20:41:08 -0500 Subject: [PATCH 117/527] Remove ImageSpecCacheFile --- imagekit/files.py | 21 ------------------- .../management/commands/warmimagecache.py | 4 ++-- imagekit/models/fields/utils.py | 4 ++-- imagekit/specs/__init__.py | 4 ++-- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index d92389a7..869b9b71 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -149,27 +149,6 @@ def generate(self): self.generator.image_cache_backend)) -class ImageSpecCacheFile(GeneratedImageCacheFile): - def __init__(self, generator, source_file): - super(ImageSpecCacheFile, self).__init__(generator, - source_file=source_file) - if not self.storage: - self.storage = source_file.storage - - def get_default_filename(self): - source_filename = self.kwargs['source_file'].name - hash = md5(''.join([ - source_filename, - self.generator.get_hash(), - ]).encode('utf-8')).hexdigest() - # TODO: Since specs can now be dynamically generated using hints, can we move this into the spec constructor? i.e. set self.format if not defined. This would get us closer to making ImageSpecCacheFile == GeneratedImageCacheFile - ext = suggest_extension(source_filename, self.generator.format) - return os.path.normpath(os.path.join( - settings.IMAGEKIT_CACHE_DIR, - os.path.splitext(source_filename)[0], - '%s%s' % (hash, ext))) - - class IKContentFile(ContentFile): """ Wraps a ContentFile in a file-like object with a filename and a diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index db8ebaab..8515325f 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -1,6 +1,6 @@ from django.core.management.base import BaseCommand import re -from ...files import ImageSpecCacheFile +from ...files import GeneratedImageCacheFile from ...registry import generator_registry, source_group_registry @@ -26,7 +26,7 @@ def handle(self, *args, **options): self.stdout.write(' %s\n' % source_file) try: # TODO: Allow other validation actions through command option - ImageSpecCacheFile(spec, source_file).validate() + GeneratedImageCacheFile(spec, source_file=source_file).validate() except Exception, err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index efba3035..2fded119 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...files import ImageSpecCacheFile +from ...files import GeneratedImageCacheFile from django.db.models.fields.files import ImageField @@ -30,7 +30,7 @@ def __get__(self, instance, owner): else: source_file = image_fields[0] spec = self.field.get_spec() # TODO: What "hints" should we pass here? - file = ImageSpecCacheFile(spec, source_file) + file = GeneratedImageCacheFile(spec, source_file=source_file) instance.__dict__[self.attname] = file return file diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 2f416763..3abcfbc5 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -3,7 +3,7 @@ import os import pickle from ..exceptions import UnknownExtensionError -from ..files import ImageSpecCacheFile, IKContentFile +from ..files import GeneratedImageCacheFile, IKContentFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..processors import ProcessorPipeline @@ -48,7 +48,7 @@ def generate(self, source_file, filename=None): # TODO: I don't like this interface. Is there a standard Python one? pubsub? def _handle_source_event(self, event_name, source_file): - file = ImageSpecCacheFile(self, source_file) + file = GeneratedImageCacheFile(self, source_file=source_file) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) From 7ed404f096960a49faf56a6aebce72093631c751 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 20:45:34 -0500 Subject: [PATCH 118/527] Switch args back to old order --- imagekit/registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index 4147f877..ccc9b7e0 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -131,7 +131,7 @@ class Register(object): Register specs and sources. """ - def spec(self, id, spec): + def spec(self, spec, id=None): generator_registry.register(spec, id) def sources(self, spec_id, sources): From 5ecb491e653d935a17b5d2c722b814ea1bf63e3b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 20:47:55 -0500 Subject: [PATCH 119/527] Remove unused import --- imagekit/files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/files.py b/imagekit/files.py index 869b9b71..1922ca6c 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -6,7 +6,7 @@ import os import pickle from .signals import before_access -from .utils import (suggest_extension, format_to_mimetype, format_to_extension, +from .utils import (format_to_mimetype, format_to_extension, extension_to_mimetype, get_logger, get_singleton) From 7bc82d3624f80ac3077f1a4c9434583f97039a66 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 21:20:33 -0500 Subject: [PATCH 120/527] Remove arguments from generate() method Previously, we had two places where we were passing kwargs that affected the image generation: the ImageSpec constructor and the generate method. These were essentially partial applications. With this commit, there's only one partial application (when the spec is instantiated), and the generate method is called without arguments. Therefore, specs can now be treated as generic generators whose constructors just happen to accept a source_file. --- imagekit/files.py | 17 +++-------------- imagekit/management/commands/warmimagecache.py | 4 ++-- imagekit/models/fields/utils.py | 4 ++-- imagekit/specs/__init__.py | 8 ++++++-- imagekit/templatetags/imagekit.py | 4 ++-- 5 files changed, 15 insertions(+), 22 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 1922ca6c..041cbd58 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -81,19 +81,13 @@ class GeneratedImageCacheFile(BaseIKFile, ImageFile): it. """ - def __init__(self, generator, name=None, *args, **kwargs): + def __init__(self, generator, name=None): """ :param generator: The object responsible for generating a new image. - :param args: Positional arguments that will be passed to the generator's - ``generate()`` method when the generation is called for. - :param kwargs: Keyword arguments that will be apssed to the generator's - ``generate()`` method when the generation is called for. """ self._name = name self.generator = generator - self.args = args - self.kwargs = kwargs storage = getattr(generator, 'storage', None) if not storage: storage = get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, @@ -101,12 +95,7 @@ def __init__(self, generator, name=None, *args, **kwargs): super(GeneratedImageCacheFile, self).__init__(storage=storage) def get_default_filename(self): - # FIXME: This won't work if args or kwargs contain a file object. It probably won't work in many other cases as well. Better option? - hash = md5(''.join([ - pickle.dumps(self.args), - pickle.dumps(self.kwargs), - self.generator.get_hash(), - ]).encode('utf-8')).hexdigest() + hash = self.generator.get_hash() ext = format_to_extension(self.generator.format) return os.path.join(settings.IMAGEKIT_CACHE_DIR, '%s%s' % (hash, ext)) @@ -134,7 +123,7 @@ def validate(self): def generate(self): # Generate the file - content = self.generator.generate(*self.args, **self.kwargs) + content = self.generator.generate() actual_name = self.storage.save(self.name, content) if actual_name != self.name: diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 8515325f..21db47c1 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -19,14 +19,14 @@ def handle(self, *args, **options): for spec_id in specs: self.stdout.write('Validating spec: %s\n' % spec_id) - spec = generator_registry.get(spec_id) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) for source in source_group_registry.get(spec_id): for source_file in source.files(): if source_file: + spec = generator_registry.get(spec_id, source_file=source_file) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) self.stdout.write(' %s\n' % source_file) try: # TODO: Allow other validation actions through command option - GeneratedImageCacheFile(spec, source_file=source_file).validate() + GeneratedImageCacheFile(spec).validate() except Exception, err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 2fded119..07c6e9e7 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -29,8 +29,8 @@ def __get__(self, instance, owner): self.attname)) else: source_file = image_fields[0] - spec = self.field.get_spec() # TODO: What "hints" should we pass here? - file = GeneratedImageCacheFile(spec, source_file=source_file) + spec = self.field.get_spec(source_file=source_file) # TODO: What "hints" should we pass here? + file = GeneratedImageCacheFile(spec) instance.__dict__[self.attname] = file return file diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 3abcfbc5..961e89ff 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -48,7 +48,7 @@ def generate(self, source_file, filename=None): # TODO: I don't like this interface. Is there a standard Python one? pubsub? def _handle_source_event(self, event_name, source_file): - file = GeneratedImageCacheFile(self, source_file=source_file) + file = GeneratedImageCacheFile(self) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) @@ -88,17 +88,21 @@ class ImageSpec(BaseImageSpec): def __init__(self, **kwargs): self.processors = self.processors or [] + self.kwargs = kwargs super(ImageSpec, self).__init__() def get_hash(self): return md5(''.join([ + pickle.dumps(self.kwargs), pickle.dumps(self.processors), str(self.format), pickle.dumps(self.options), str(self.autoconvert), ]).encode('utf-8')).hexdigest() - def generate(self, source_file, filename=None): + def generate(self): + source_file = self.kwargs['source_file'] + filename = self.kwargs.get('filename') img = open_image(source_file) original_format = img.format diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index f114a808..9c9f690b 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -31,8 +31,8 @@ def render(self, context): variable_name = self.get_variable_name(context) generator_id = self.generator_id.resolve(context) kwargs = self.get_kwargs(context) - generator = generator_registry.get(generator_id) - context[variable_name] = GeneratedImageCacheFile(generator, **kwargs) + generator = generator_registry.get(generator_id, **kwargs) + context[variable_name] = GeneratedImageCacheFile(generator) return '' From 20c900df4afcc5cba17a790eb663cb2818f9fad1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 21:52:23 -0500 Subject: [PATCH 121/527] Remove unused imports --- imagekit/files.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 041cbd58..5c7b5ee5 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,9 +2,7 @@ from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode -from hashlib import md5 import os -import pickle from .signals import before_access from .utils import (format_to_mimetype, format_to_extension, extension_to_mimetype, get_logger, get_singleton) From 236eea8459975de8f0f5eec593fe2f302a6ee8e6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 22:09:34 -0500 Subject: [PATCH 122/527] Move filename generation to generator --- imagekit/files.py | 12 +++--------- imagekit/specs/__init__.py | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 5c7b5ee5..52836dec 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -4,8 +4,8 @@ from django.utils.encoding import smart_str, smart_unicode import os from .signals import before_access -from .utils import (format_to_mimetype, format_to_extension, - extension_to_mimetype, get_logger, get_singleton) +from .utils import (format_to_mimetype, extension_to_mimetype, get_logger, + get_singleton) class BaseIKFile(File): @@ -92,14 +92,8 @@ def __init__(self, generator, name=None): 'file storage backend') super(GeneratedImageCacheFile, self).__init__(storage=storage) - def get_default_filename(self): - hash = self.generator.get_hash() - ext = format_to_extension(self.generator.format) - return os.path.join(settings.IMAGEKIT_CACHE_DIR, - '%s%s' % (hash, ext)) - def _get_name(self): - return self._name or self.get_default_filename() + return self._name or self.generator.get_filename() def _set_name(self, value): self._name = value diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 961e89ff..effd56ee 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -7,7 +7,8 @@ from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..processors import ProcessorPipeline -from ..utils import open_image, extension_to_format, img_to_fobj +from ..utils import (open_image, extension_to_format, img_to_fobj, + suggest_extension) from ..registry import generator_registry, register @@ -40,9 +41,6 @@ def __init__(self, **kwargs): self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) - def get_hash(self): - raise NotImplementedError - def generate(self, source_file, filename=None): raise NotImplementedError @@ -91,6 +89,17 @@ def __init__(self, **kwargs): self.kwargs = kwargs super(ImageSpec, self).__init__() + def get_filename(self): + source_filename = self.kwargs['source_file'].name + ext = suggest_extension(source_filename, self.format) + return os.path.normpath(os.path.join( + settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0], + '%s%s' % (self.get_hash(), ext))) + + return os.path.join(settings.IMAGEKIT_CACHE_DIR, + '%s%s' % (hash, ext)) + def get_hash(self): return md5(''.join([ pickle.dumps(self.kwargs), From 14d2193f8d00200e16de9dcf2aa5866a0b9e25ab Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 22:23:25 -0500 Subject: [PATCH 123/527] Remove unused args --- imagekit/specs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index effd56ee..60d4d9a5 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) - def generate(self, source_file, filename=None): + def generate(self): raise NotImplementedError # TODO: I don't like this interface. Is there a standard Python one? pubsub? From 848d7d7fa3399b33c9f37640226cbf2e4e6415b4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 1 Dec 2012 23:18:49 -0500 Subject: [PATCH 124/527] Add TODOs --- imagekit/specs/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 60d4d9a5..581453dc 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -110,6 +110,8 @@ def get_hash(self): ]).encode('utf-8')).hexdigest() def generate(self): + # TODO: Move into a generator base class + # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) source_file = self.kwargs['source_file'] filename = self.kwargs.get('filename') img = open_image(source_file) From 4f81e14f58695fb3b3a505d27c61d71d56fd7882 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 21:06:15 -0500 Subject: [PATCH 125/527] Re-add html attribute handling --- imagekit/templatetags/imagekit.py | 118 ++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 38 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 9c9f690b..31694813 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,4 +1,6 @@ from django import template +from django.utils.html import escape +from django.utils.safestring import mark_safe from .compat import parse_bits from ..files import GeneratedImageCacheFile from ..registry import generator_registry @@ -7,35 +9,70 @@ register = template.Library() +ASSIGNMENT_DELIMETER = 'as' +HTML_ATTRS_DELIMITER = 'with' + + +_kwarg_map = { + 'from': 'source_file', +} + + +def get_cache_file(context, generator_id, generator_kwargs): + generator_id = generator_id.resolve(context) + kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, + v in generator_kwargs.items()) + generator = generator_registry.get(generator_id, **kwargs) + return GeneratedImageCacheFile(generator) + + class GenerateImageAssignmentNode(template.Node): - _kwarg_map = { - 'from': 'source_file', - } - def __init__(self, variable_name, generator_id, **kwargs): - self.generator_id = generator_id - self.kwargs = kwargs + def __init__(self, variable_name, generator_id, generator_kwargs): + self._generator_id = generator_id + self._generator_kwargs = generator_kwargs self._variable_name = variable_name def get_variable_name(self, context): return unicode(self._variable_name) - def get_kwargs(self, context): - return dict((self._kwarg_map.get(k, k), v.resolve(context)) for k, - v in self.kwargs.items()) - def render(self, context): from ..utils import autodiscover autodiscover() variable_name = self.get_variable_name(context) - generator_id = self.generator_id.resolve(context) - kwargs = self.get_kwargs(context) - generator = generator_registry.get(generator_id, **kwargs) - context[variable_name] = GeneratedImageCacheFile(generator) + context[variable_name] = get_cache_file(context, self._generator_id, + self._generator_kwargs) return '' +class GenerateImageTagNode(template.Node): + + def __init__(self, generator_id, generator_kwargs, html_attrs): + self._generator_id = generator_id + self._generator_kwargs = generator_kwargs + self._html_attrs = html_attrs + + def render(self, context): + from ..utils import autodiscover + autodiscover() + + file = get_cache_file(context, self._generator_id, + self._generator_kwargs) + attrs = dict((k, v.resolve(context)) for k, v in + self._html_attrs.items()) + + # Only add width and height if neither is specified (for proportional + # scaling). + if not 'width' in attrs and not 'height' in attrs: + attrs.update(width=file.width, height=file.height) + + attrs['src'] = file.url + attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in + attrs.items()) + return mark_safe(u'' % attr_str) + + #@register.tag def generateimage(parser, token): """ @@ -43,37 +80,42 @@ def generateimage(parser, token): """ + varname = None + html_bits = [] bits = token.split_contents() tag_name = bits.pop(0) - if bits[-2] == 'as': + if bits[-2] == ASSIGNMENT_DELIMETER: varname = bits[-1] bits = bits[:-2] + elif HTML_ATTRS_DELIMITER in bits: + index = bits.index(HTML_ATTRS_DELIMITER) + html_bits = bits[index + 1:] + bits = bits[:index] + + if not html_bits: + raise template.TemplateSyntaxError('Don\'t use "%s" unless you\'re' + ' setting html attributes.' % HTML_ATTRS_DELIMITER) + + args, kwargs = parse_bits(parser, bits, ['generator_id'], 'args', 'kwargs', + None, False, tag_name) + + if len(args) != 1: + raise template.TemplateSyntaxError('The "%s" tag requires exactly one' + ' unnamed argument (the generator id).' % tag_name) + + generator_id = args[0] - # (params, varargs, varkwargs, defaults) = getargspec(g) - # (params, 'args', 'kwargs', defaults) = getargspec(g) - - args, kwargs = parse_bits(parser, bits, - ['generator_id'], 'args', 'kwargs', None, - False, tag_name) - if len(args) != 1: - raise template.TemplateSyntaxError("The 'generateimage' tag " - ' requires exactly one unnamed argument.') - generator_id = args[0] - return GenerateImageAssignmentNode(varname, generator_id, **kwargs) + if varname: + return GenerateImageAssignmentNode(varname, generator_id, kwargs) else: - raise Exception('!!') - # elif len(bits) > 1: - # return GenerateImageTagNode( - # parser.compile_filter(bits[0]), # spec id - # parser.compile_filter(bits[1]), # source file - # bits[2:], # html attributes - # ) - # else: - # raise template.TemplateSyntaxError('\'generateimage\' tags must be in the form' - # ' "{% generateimage id image %}" or' - # ' "{% generateimage id image' - # ' as varname %}"') + html_args, html_kwargs = parse_bits(parser, html_bits, [], 'args', + 'kwargs', None, False, tag_name) + if len(html_args): + raise template.TemplateSyntaxError('All "%s" tag arguments after' + ' the "%s" token must be named.' % (tag_name, + HTML_ATTRS_DELIMITER)) + return GenerateImageTagNode(generator_id, kwargs, html_kwargs) generateimage = register.tag(generateimage) From 4f7ce6890416fa8d660561f7eeecd082d91f136d Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 21:11:52 -0500 Subject: [PATCH 126/527] Add documentation for generateimage --- imagekit/templatetags/imagekit.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 31694813..a1731a5a 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -78,6 +78,28 @@ def generateimage(parser, token): """ Creates an image based on the provided arguments. + By default:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image %} + + generates an ```` tag:: + + + + You can add additional attributes to the tag using "with". For example, + this:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image with alt="Hello!" %} + + will result in the following markup:: + + Hello! + + For more flexibility, ``generateimage`` also works as an assignment tag:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image as th %} + + """ varname = None From a499f5fbe63f03a3c404a28e0c1286af74382e09 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 22:24:55 -0500 Subject: [PATCH 127/527] Add util for generating named image file --- tests/utils.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 746920fa..89d29740 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -3,11 +3,12 @@ from django.core.files.base import ContentFile from imagekit.lib import Image, StringIO +from tempfile import NamedTemporaryFile from .models import Photo import pickle -def get_image_file(): +def _get_image_file(file_factory): """ See also: @@ -16,12 +17,20 @@ def get_image_file(): """ path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', 'lenna-800x600-white-border.jpg') - tmp = StringIO() + tmp = file_factory() tmp.write(open(path, 'r+b').read()) tmp.seek(0) return tmp +def get_image_file(): + return _get_image_file(StringIO) + + +def get_named_image_file(): + return _get_image_file(NamedTemporaryFile) + + def create_image(): return Image.open(get_image_file()) From a5c33a4925668c0a5315ac67e5df433ee78216e7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 22:25:12 -0500 Subject: [PATCH 128/527] Add tests for generateimage template tag Currently, these will fail because the temporary file cannot be pickled in order to generate a hash. --- setup.py | 1 + tests/imagespecs.py | 8 ++++ tests/test_generateimage_tag.py | 65 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 tests/imagespecs.py create mode 100644 tests/test_generateimage_tag.py diff --git a/setup.py b/setup.py index 985e103b..7c1495e3 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ zip_safe=False, include_package_data=True, tests_require=[ + 'beautifulsoup4==4.1.3', 'nose==1.2.1', 'nose-progressive==1.3', 'django-nose==1.1', diff --git a/tests/imagespecs.py b/tests/imagespecs.py new file mode 100644 index 00000000..536db7a2 --- /dev/null +++ b/tests/imagespecs.py @@ -0,0 +1,8 @@ +from imagekit import ImageSpec, register + + +class TestSpec(ImageSpec): + pass + + +register.spec(TestSpec, 'testspec') diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py new file mode 100644 index 00000000..a7214aea --- /dev/null +++ b/tests/test_generateimage_tag.py @@ -0,0 +1,65 @@ +from bs4 import BeautifulSoup +from django.template import Context, Template, TemplateSyntaxError +from nose.tools import eq_, assert_not_in, raises, assert_not_equal +from . import imagespecs +from .utils import get_named_image_file + + +def render_tag(ttag): + img = get_named_image_file() + img.name = 'tmp' # FIXME: If we don't do this, we get a SuspiciousOperation + template = Template('{%% load imagekit %%}%s' % ttag) + context = Context({'img': img}) + return template.render(context) + + +def get_html_attrs(ttag): + return BeautifulSoup(render_tag(ttag)).img.attrs + + +def test_img_tag(): + ttag = r"""{% generateimage 'testspec' from=img %}""" + attrs = get_html_attrs(ttag) + expected_attrs = set(['src', 'width', 'height']) + eq_(set(attrs.keys()), expected_attrs) + for k in expected_attrs: + assert_not_equal(attrs[k].strip(), '') + + +def test_img_tag_attrs(): + ttag = r"""{% generateimage 'testspec' from=img with alt="Hello" %}""" + attrs = get_html_attrs(ttag) + eq_(attrs.get('alt'), 'Hello') + + +@raises(TemplateSyntaxError) +def test_dangling_with(): + ttag = r"""{% generateimage 'testspec' from=img with %}""" + render_tag(ttag) + + +@raises(TemplateSyntaxError) +def test_with_assignment(): + """ + You can either use generateimage as an assigment tag or specify html attrs, + but not both. + + """ + ttag = r"""{% generateimage 'testspec' from=img with alt="Hello" as th %}""" + render_tag(ttag) + + +def test_single_dimension_attr(): + """ + If you only provide one of width or height, the other should not be added. + + """ + ttag = r"""{% generateimage 'testspec' from=img with width="50" %}""" + attrs = get_html_attrs(ttag) + assert_not_in('height', attrs) + + +def test_assignment_tag(): + ttag = r"""{% generateimage 'testspec' from=img as th %} {{ th.url }}""" + html = render_tag(ttag) + assert_not_equal(html.strip(), '') From a07bc49a25e2ef0a114077b1f2445f5984df3949 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 22:41:02 -0500 Subject: [PATCH 129/527] Remove inner Config classes --- imagekit/registry.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index ccc9b7e0..59612981 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,4 +1,4 @@ -from .exceptions import AlreadyRegistered, NotRegistered, MissingGeneratorId +from .exceptions import AlreadyRegistered, NotRegistered from .signals import (before_access, source_created, source_changed, source_deleted) @@ -13,27 +13,12 @@ class GeneratorRegistry(object): def __init__(self): self._generators = {} - def register(self, generator, id=None): - # TODO: Should we really allow a nested Config class, since it's not necessarily associated with its container? - config = getattr(generator, 'Config', None) - - if id is None: - id = getattr(config, 'id', None) - - if id is None: - raise MissingGeneratorId('No id provided for %s. You must either' - ' pass an id to the register function, or add' - ' an id attribute to the inner Config class of' - ' your spec or generator.' % generator) - + def register(self, generator, id): if id in self._generators: raise AlreadyRegistered('The spec or generator with id %s is' ' already registered' % id) self._generators[id] = generator - source_groups = getattr(config, 'source_groups', None) or [] - source_group_registry.register(id, source_groups) - def unregister(self, id, generator): try: del self._generators[id] From 956601b5d0c8f3059b84657224f8b0d8f11e4f76 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 22:48:14 -0500 Subject: [PATCH 130/527] Revert register.spec argument order Since we got rid of inner Config classes, we can put the order back and support decorators. --- imagekit/registry.py | 6 +++--- imagekit/specs/__init__.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index 59612981..a547c690 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -13,7 +13,7 @@ class GeneratorRegistry(object): def __init__(self): self._generators = {} - def register(self, generator, id): + def register(self, id, generator): if id in self._generators: raise AlreadyRegistered('The spec or generator with id %s is' ' already registered' % id) @@ -116,8 +116,8 @@ class Register(object): Register specs and sources. """ - def spec(self, spec, id=None): - generator_registry.register(spec, id) + def spec(self, id, spec): + generator_registry.register(id, spec) def sources(self, spec_id, sources): source_group_registry.register(spec_id, sources) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 581453dc..906f210f 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -185,7 +185,7 @@ def set_spec_id(self, id): """ self.spec_id = id - register.spec(self._original_spec, id) + register.spec(id, self._original_spec) def get_spec(self, **kwargs): """ From afc5900db65fb69f18ec5e0769218a82d568aadc Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Dec 2012 22:49:32 -0500 Subject: [PATCH 131/527] Support decorator syntax for register.spec --- imagekit/registry.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index a547c690..c6d0150b 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -116,7 +116,14 @@ class Register(object): Register specs and sources. """ - def spec(self, id, spec): + def spec(self, id, spec=None): + if spec is None: + # Return a decorator + def decorator(cls): + self.spec(id, cls) + return cls + return decorator + generator_registry.register(id, spec) def sources(self, spec_id, sources): From ea962b6259f689995cbb3ceabae1f0edbc045122 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Dec 2012 22:48:02 -0500 Subject: [PATCH 132/527] Correct argument order Related: 2cc72cd --- tests/imagespecs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/imagespecs.py b/tests/imagespecs.py index 536db7a2..8a699751 100644 --- a/tests/imagespecs.py +++ b/tests/imagespecs.py @@ -5,4 +5,4 @@ class TestSpec(ImageSpec): pass -register.spec(TestSpec, 'testspec') +register.spec('testspec', TestSpec) From 7f11f44c67e0cf3890cfc64c15443a27ebc20441 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Dec 2012 22:48:40 -0500 Subject: [PATCH 133/527] Special case source_file for specs It was already special. Why hide it? Closes #173 --- imagekit/specs/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 906f210f..b884eac5 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -84,13 +84,14 @@ class ImageSpec(BaseImageSpec): """ - def __init__(self, **kwargs): + def __init__(self, source_file, **kwargs): + self.source_file = source_file self.processors = self.processors or [] self.kwargs = kwargs super(ImageSpec, self).__init__() def get_filename(self): - source_filename = self.kwargs['source_file'].name + source_filename = self.source_file.name ext = suggest_extension(source_filename, self.format) return os.path.normpath(os.path.join( settings.IMAGEKIT_CACHE_DIR, @@ -102,6 +103,7 @@ def get_filename(self): def get_hash(self): return md5(''.join([ + self.source_file.name, pickle.dumps(self.kwargs), pickle.dumps(self.processors), str(self.format), @@ -112,7 +114,7 @@ def get_hash(self): def generate(self): # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) - source_file = self.kwargs['source_file'] + source_file = self.source_file filename = self.kwargs.get('filename') img = open_image(source_file) original_format = img.format From 938e2e178b103c50cfbf5a0a4c43167c889c15a8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Dec 2012 23:11:05 -0500 Subject: [PATCH 134/527] Clean up test utils; write to media dir --- .gitignore | 3 ++- tests/media/lenna.png | Bin 0 -> 473831 bytes tests/test_generateimage_tag.py | 5 ++--- tests/utils.py | 23 +++++------------------ 4 files changed, 9 insertions(+), 22 deletions(-) create mode 100644 tests/media/lenna.png diff --git a/.gitignore b/.gitignore index f013ec3c..7380ca53 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ MANIFEST build dist -/tests/media +/tests/media/* +!/tests/media/lenna.png diff --git a/tests/media/lenna.png b/tests/media/lenna.png new file mode 100644 index 0000000000000000000000000000000000000000..59ef68aabd033341028ccd2b1f6c5871c02b9d7b GIT binary patch literal 473831 zcmV)CK*GO?P)P{hp-DtRRCwC#;a!q#Taq2-jp6QduC*iLoO?5?APD4(S|Fp0Mp2~kPbH(7IwPY1 z>QxO;$ z!H&NHZz`L^k6^>6rMeRnO;j%9d+4>g2Jct(qkjE&%Z@(&H|x*;`21Y@<@47#etfR| zb(Qhz*nQag#Xf%j7<;d;aU9By2vQ*fl4axcvdwJC(7Oekv*EL=)oc?$R#+qoRrDwf z=PezHrM+o3x@e=K1}5IzKbM91@CYI^ul;y`OH_NCAFOBg$HTr%LvJ3**WOVbW7L~R zwrIA?&U3BBZrXcU+kWNy@2CCfyJf4;4p;V=Tzkbibaij>(VY{!@rFQ$ zeEVYi?jG{pnn4=(r5J$?JdmGxeq$v%v%iI3l#IBFWy8)7KK~q5{r>x2pRBueo1KL- z^Vf%2ISledsbSxXo4Nb#U0p*@*n93gwF+e+R38r;gM<&}^DEl`*}k?B{r>Pp)0KkT!MTB`=S$|qYJc;Vale8Gj!_%a z)_S&uUN#R~SC4Pz#^;YsxAPp?%B?s$HxA{?5N$SjzZ7(39zXN`^EJQo>!on&uzaC% z9S2)WU7{+xx(s2KKc2glJihm*zmLhEIer`#^Wz-RHl}H4hMRa4{HN%bv+8jeHqjiX z)}6-(^z!Emdhge7#?T?&UZ=Pbt$hw(7w6B}?)59jJ9T$EARXVlU(C<)Z>%5I?AmyI z)5_Lz3)83Ut?D4Z2s1(5K;(z}-9SnyO}D$pckHcWQrQ~5?+M>hyS8HT42+CMV> zDgBQJ9_N2J#^3%;oaT>rx_msuO+6S!3lQF0RUHn?`Ssg={jZ zKo#YfXRbe+y^Xvo6CdxjGVEFSn|}S;bMDWYkFL8IXYKh)jt^i>aYIlum0-aONPJttH1iIzxwx*;jjMcum0+<{=H=QtH1iIzxu0x zFZsXtzy6mr+5KzP%WN2{i-A|+%iDGTs+i2rzQgb|Es!DUx}3Xnv*kH?KYhFrn^hWW z{cQEg@k#TJ;N>YQf02J!J%ip3c4`dw0hw7feVBO`%k+@d1N@V%liYm$w&}f9een6b zfBo~iGQs=R6-*87u1@zx?^CVnpd68Q;?}5FJwE3CtP$+Al}5@Nt=uqcyH(Lg-*~MW zK3BF>CKa@n`N8!SgSxWarY#-sxOT_rKwJxc;O!XerT~YHFpSbN(pc(qw8un)c-?Iy z=q_cuvOD{*>@l-q)SZvBWYlGS8=Kv|~7fyv@IZfVo=%MuAq83EeDn113-q zVT-TcjpvWgx^`!IoStd@!rSjmucaQxd*vE*X+Qb}IGM+K)_J&A`3Li}eNL@D-lXnu zFEa14oX#sZ7@g?Dd|kUET-FzTa7s4O1lF{oAHB1B_n2W_wT1Fys4w+VO2@`{jQrB> zjB$Fla*(!VvCS!)g^e=TE?`hD>s9O>$A?@a%nmc-IbhE}UCY0I`^R7Z-Phm$kAL|8 z{(t`b|NbA+|NH;uKWBA6z&7CYxU7ME!6tm5V3Sr~@-{+SRB8UL^z;oL@4db(4x-bH z0!#Gr`>IBp+wq_bqT6Mh=I887hXtbNVP(d9z=TOH_6>h)->P@k7q*#FVs^8#@|hZS zy|O~<>htmXd}g2d+%&7Jd(6v5%tx=qIeazh_P%^PsKPNh2kvXPnQiNcc*_w}!x~_?~-UE>Ln50vS2xAsN$G}ibVzHWEgozdm&w)****LamnkAYM8D#Fq<^3?AI5qhZ^c8lalEUFSH}b5 zT#UGOPto787xg09VLBd1HO5i)9ankC9m{c4D|bh@ljc@893642q#JOp@e^8F+Xg`g zx|_qS=6kHqs4ffRXjGNCiIuE6Dhbtgf>+s8w-58Ub*jkq!ZBJ^dKho5m(?BCHBT54 z9`*Tf(oSBVc$gPt)}1JBa)ARI{${1H7h27^YrCwFqd~NSYNj3Z2lrCL!OmX21|W6s z#YQoT-FuJsITi2*BatD|k=xnH$wzu0lqy=dl5x%FCO9z5u>8zrO#6 zKiq#*&v1^;REx_oD z6rqF-^(<}++db~|*$YP4cV<%AB30}*5ZLqqHHJDf=r!M+cd@Agz0ZNQH6FTegjWZc z(6AWDrz)+=HMADa4@=FAAn&!DP)ICTwD-a8Tp~@cFo)0) z)xEt656uxws_XcM`keLU5vuko)YgGv1P;$?XE*iuCrAC}eKcXpjR(W5%`Jm8v$;Pp zf+`u~y2{@Q=_os9m4-39l|wskHd~<772c(4$Aj;YE3MOx8P?ZwnBLAuUmXuCFldkO zgC!rLxn3H>A8*Wd{7_p!;=wtXgl+igc`JVI5Y`hIs2kk0Z@}Vuxu4V$q&5R(h|Jjmsd=c-WKHX{ym4}ipi8);OVNLy%!f)cGLqf!;ng=0rEGS-_pI@mMo_eFeJh5mMdNF*2JwWYrcUFV3U7`|-PncB6xDwLgd3mPXj& ztjuH>;cn{OrFa~kg{{L9P^#VM*h}4tBU?n-qKGjx+gA*azeQN@HKNTw!c#bmRXt=L zfVp|K9X=4kvewmjet!Moe}4VzKm7O~|M1(t`8@vBKYU)8&#&A6#ee<3XWxoxESQUL zp|3LMdE&kuPhj)}tK7vgDUrhC5Dv3v*D(L^%sL;ImW|+}(Nc0g*e+J*bi6#y7$`f( ze2~w498t;hC+^E2Wr@pX(;Clh*aEo=y*s_uT`5YPx9srey*v8)TIaWQ-wp5X?J&gK zfcdb1Tw|Q%ZR5MFxnJJmdIlBqaAbkgdll*tuId(BJQU^`W8~)H+6iSpzQvp8v)z+? z(_ZmyR8PiS%`ht4={g?hEd{Wxyv+N)vlwygjEU7|`SvqvNy#uC*jc<%{&{Y-B0s`4_-Hr$-{b=NV6^qY*fTXIa+iUZ+?8#m54W3TVHenFjU4d z_p^CKY&{N0+ArE}P0INn&qqES!E6*DCP{P zZdhQWi#)WR2>J|FJ`RFV0uicIme?li>!$5IV^DstjU%ij;#D$lwRd6!dZ2FE?8k`v zRpa-zo(3aAMyrN|LFl%GVCXy49U;;T;E8$x?8E&3FKMUsXU)?(+;6ZrCsB@9Y1n8) z8-G%MVN7>tC&o~`dEPRC65qYE-B8QS5Z@F6h4^Mb+toZ}L8Ef|`i*!OTm2Nhyy zx$Lz^Jj=fR@$vO=W#KqL_2?p+TnHL~FAF*tG3?=W+T7rW!O- zJ81`_`#kK~6*WY-9A?5CnD?c}d+HVrfBT)KEXz7~^?1Ja{5g8}j`Z8WK0~s+p2%)2 zGn?2pjlI>I*Q@b{O7Dis##?4u3~w~SLR*_p@6F3<-)yi=Ce_tztH&NdQdt#4-m0;y zhRT?-8R|Ak>6Btr_Asx#EwkE;E^b=Lhjt=`h-r!~L)CaIwok@gjV^mfzA)Un&BF1d zy_o}m!aF=P>GZx{WxvV zyy$N*14VDq%r+2BcQpVr0NL>%iv7jw9liUR)jg`a%<4LfjfZ=p*y9+?ZPWM5TjpWP zPF6T^o6auCyU=VqYIm2-li|4*;t&$pyN`YS`1;4MU+(?K zPyYQcU;mJKFKefX((c^;&;RcKNV1WLld926I+ZWPO?#u2_a#5EZu4lsDEf!`>Gr)w zxISTSbvBloaFG>q9#QvA$-U+8q{uJ9t?7qB+kId+@q(LtI-(=|^=k=KU|oo%%jCtj zdTrdVChPTN{6xbBdR=>Im+F?ON*Nl#Txt%|0e+@I> z#cZ*TFlyj*-v-3arW#;|DFdZ(!0Z@1^`^XrGuI1a zvI$R98s2R#WHD1ljPR83a+w>(TN3+r9-+1C zd}Ft(d);{)LyZ~EgOp8oQ;F`w{(^ro&4Or)lLk0!3p4zB61V2>R4=Y)`{5YAZ**`p zb4EYi-Y^704#ESg?U!u=O+zEh6z5IH88bnFfPQ>`jw5G(0ugCit|o zcWz1EeF`$~@X64Oa3)DbEA9UL@yn%u{8fMYQ~sMj?;k(zLNG?RTFrA{4*&1|?mq*} z*skGrbx+(}@Qo#G7Cp6?_~(eD$L zmXNl0s%n%tZS>2-HD=^8F)6cB2>^QmnsMA*4|_|ikqLh!&D`P5t~?&tm$M^VF564z z#9jOCchcQkW->Lhx(&{L`yKlB0R2F>*KVc780yV4!iK!|4!{J;6{Lu6nT5Y~ZAWF8 z-KqFK>K0gl+i-;fgqJR3fK659!=~nw@oB`689^XcOdN`An zILvP8Z4O=SmQ-2@sTm;8h$5+PZk-vzs(yRhWr5Os^y{mKf!x(0)!VEBorSV-T4kT3 z*Tr%660w|;eMf)V7=)KC#ao8xVYrLmyzU&2A|}x}hu{79*>sT+{ep`+;2zn)5F2z^ z(tKfXuZe2-$jtdTbZLx@exTdb^N`T0+XO|%1Fzr0NLi1`*UMri;K#SDuG&Xi8*ogQ zn74%)N*o^Q7STk+di6P2q+OKM5rnh@)<&z1^TY7!U=_)98f{leHvDe0qs+Y9uzRKs9a=T&+o4f(cCxvjlwleSgwEu55N2#{%s24KG$^YN z!>##-%%VdqwC;9)=dn19MtT{IGI1G5I$VUoz7boPWH%c1%r<--nL9tX%WO-^PamMPBIV$z@ zQd&q6n|RY5k!i!grEu1`G7-iTZb4L+Da#9+>^8W<9d&s3`E#r0UT}vGMy=;{-Tw7? z|M5@HKmPLimp}GrW8GO`?#&=YCBXFm$KU-I1_xz(fH(81_rJkd2uCG3S#(KV;0YAz z-JA2M3a8A|@Yo}G|G;^o1sN-4sGRn21EKJD!#sTfMh>%MiZ`3|WFC%JUX%Ta3Hvqo zaj^ff`}ZA}?#i~V&9%x(JiBh>s$IM6-Wx72d)>Ffr{pUC_OXrny#4TyWX7=Y&^V@6 z;cTN*n0XlG#yc49A^ zNDdiY8`C9LmpSVFC)Vw102U=2l$l8096z&v!^byXqxQ0JImGY^p3fMx;~Sl%!NS-? zXuJ`Ey`z(MLuS^nY1)lYday^1Z8w^R^_K?-$62poqxX02s@l*upi zqeah(AvmkT^W{#A)4u-f;3RLnzl~lf6Z+%#zCU3@{TkBIH&%OY!@lv|_AP1*M`dEd zWtPLtxlBz+3+1)r_v(#^-n+&To;VrF2(~A7A&MzUoi^c>UqkU$-ZZTrcxz zmN}rIc?aeH{onl`h!g{sngjh2{To2?S2a7ckq}V-W2OPA5lFkGf^v1Kwqa+Zc@x?dRw=Gx_PgxmRnLJnAI`{-U!P z2%9OwnnU-EaD1%h2IgF2ot@%ZYkFt;4#!HqT)@sla}5S{JRiVOW0|CS~On zhWiLIXxkD^k5*<+w>m%g_3HD@8rave8HmX8+WqlUFO&`Li{_&Xxy&COhS#e(_&9KX zVZN&tRq3Z$(P3js<_nzU`OaDv;T7z=(sUeyUe6U|&yczv-$sG=3te^|y=t#@R(&z1 z8KWG&?eN~EL^AylHJuoP$H&m}0|>T))n=RHgEpvw4JPV*(0}uu9#BI}+O`?KvWIcI zc!0yX?0j@5A~a~4X0)%1BQl0pS`D)#+E*bA8{P}&?`wZqFge0nv6K(srj=FWzBnF0 zK_A{f)XfPj18Vp(#Wo~!QV z$Km${5{aG>XpQ$#FCuFkkk{i7#k}C>QTwh9>zS(uIUZnz!R%pb1>i>$c$LM1y~~>; z3}IS{uyNSwY;)ZkZxem^g84XN>{j=>@cO!b`>KEVP5?iOPbGU7 zhBFxxl!x5^#sB3$1qt&ijQn%O8~uy@7bC|S_oetAtu}X1wN*R(_gzmKxL(%S)2$J` z>$sVtxg1cnA?UPG(A3)?4_cFHesrg|H7)o<^`QP-F~LN(_#OSrmchRHme!~2jas~( zIev=QFMXqX^!vlE-0F4DRrh{;*naJlpN~O+ZkDijXKGCARJM6|tI@;5v&$;0EoeNu zbG%;uadxY_l|xw-B!(YDwTgrHO{xS7AlWwj^LsLU*&spNT7UhZ$|tK+D(6ybTbcKQ3LtrkQR4GTOB z8?7TI*0VGeq6{b$7`K(9pMekrGs{axJl@BB^-cFyDcdWvC<=HS=-Km#`!egsDEQ$< zE3el5N*l0m)U7y$jroRPAR(rA*sx)3X4kJc{)W-@`c!*7{phOfe3cx}xdK{8lUT4njE^*O{kN8U9A%oBUB$2Wd{BBpV% zRpS`wqEw8%`tg0dvZI{_$mor%<)|AS{s`puJ~hp-!~-<$A7#NVRgM?{T4o&79fGHl z0YLP@@cre-yQ|F#@U9i-H{@;D9A0GIquq}I7cS8f);~_K3X}88f=OMsfU1+H3tVFP#e)Wp6J50N`l?+Mq`Xx4i^F|CyHoil)2bCl%N@sPHB0%urQ>?yoP* zw~p;mh@VX%zTEHfcUwhsx`0U&s8eGqcM_<3&4UO%#9 z-`3CPow^?%x_4EVSu3XnN~)WxYQ^Z7fyQA1vi+EKanfZNQ}?US5k+Q3RqriWRH8Wm z1Z5U`RZMfl+Ju@u++@>cI!6Ueuj-g}$*j)z`t|Cv&bH=s$-C+4Py*F1cm)W7~Wp5{zPkZs4T2~d^2YbuATYy1^PHOjj zcdAnw9wX#$qjweToF+54_0AZ6{9L!<`J*4dx4yO82g)DTyBORLaz!tJ=~GQ-;ymzm zmpM9heCPhv;%qa{;Ops0k5<8xQmInzs&dKfc-hf;AaMGZK4sZj6J+w2hRLr%%UW>+#d>YbZ*W*G1xTpzeUVa;)C-VP^6B zv;Y2w&uLD7-O;!MaI@@5mfFstIEKlz5MFl3Mv#hZg`*I&)7%kvF8k&XY?(WAGfLy2 zXuZ_S&4r?$z{c8?0EZb^OmyF!1}|#TTQgV-Wi&>(K+~6b?0Xv;>Fy>g%#?nzeuK@(cIK;eU?fwgXZWO zUAs8B5g$6-T*H_NH#<~`JbW6%dRa2ZThuch#_8Fu80#Xt$A?|ZV$x)8Z6l5m`8E8F z$C8h*)#7nH;!%Cu=WBocxc~gwfB5zO;~&=FzwS?-*Ujp^?u)D0-Ic1%@y_R0yv^E| z|BL_TKY_X`U?qNUei=q7t!X5etXlC61hCDwZs%BDrTB*4WpCC?VQs_qpBrx`LvPF( z$M2e#bVC9VN5{G#LrUG`sXPRlDGcBXXw_AdLh^wFb zb*n17lvR8!cT;VPK!fz7?w&J*B&fz$2|B&|5zS)D-R)ZTm?U*=jfWN_<6vpo`3?8Y zU2UAr8bejAf?M1!-W&v-04J#Fdl4XSo6|`fIJR(3G$70M<>!a?K0Q=O^b~~-8=-=E zv?POF!YS)gTQ1pOka2jvG>7jy=Jb9c2kAq*&eKz1wGX;m)_6R+u3qgjPEvG5>x%R2 zc(eWLa9XQdw0!^WuOB$h?K)I@hVQ~0un&{Fe|7vc1mW)UeXJ+g=C}8o3T8VkM&H1P z>BWmw+7W(h`+!Oonboq6;Sxre(*U!HZVox4?+Z2uUl@POTAFhxK}U5bu+o~s8b@kO zuQWFC23*16O?w*z?x*GHw#nu$TA}(JOMIA~=%C}v z-j7{|oi>8OZsY}>VK@3kFuPbc#B}!8l|(o=K60-Z{+65A#ei*hTAY=aUJGwX4`J%= zQCa4k<3Ov}!4YH(tCkhH@B*d-E(;FXx)=wlZ6>CLu~Q7=-P}pujNuGw(+zC-K)h9c zv9k5fvypE-+wACTHQ(7!*zbuio$s)M4IfOn^`uL1^p?MImDLjDxv`I?$q(AW{iLhU zkKQXP>63KoOBHR-od{ZQRzZd_YS8Z+ity_Au*Vy{EDqA)4LT6SMV^4mf-tJ#Mr_)o z7E$)P*5_I{uF~!!UYC66@nEh1>-6EyYF3%bi&51a6FYp+S;nY#z!tMM7GyAB6v|om??lLRIH!?T@ zy&!MveORIB>WlVWd5ar5d{r;d$S!i}@~Y)nYfF3ezWep{{MremRQJ{QjWG`} z?`2L-v_InY#5p)m3#5F@XMqOWh{C?1)Z&nc~ z6p|Qnw^5al4G-wiNx^%Do7KgSM|8*D-Ei3g!*}n2L3gwLqNDFs&GGKImm0=1Ej`&Z zb`o6kZCZsk{QX#$=J3AgA)(v2E|TrDUB>9O%>f>YW*A94ziK?3ndTHiQfH&++%|Zx z_QC6u;loZ>^pxKacgsKE*^pGqFAcjmT)_eH#vx_|@p?u!`;mq`KIYFIPO(aK@(G3t8B-UnXkqxU|| z)U+`?0*`Oe@Q*j;XWKU#0tsuxL;C`Rb2QArf@voh@KZKm15Bf%uEt@t5l)ye%ogHo z$#g?926o~w&x`XLVZgS?=7akwfISR}a44*|e3K8kI=lU$naGWClEB_DH-ic_zOybj zcDUr|-F`sJ+A+5JK)txl!mLU;?V+$Q#;{2eW=(s*2MG2C5;jZ33Ngnd2BfVvm@2izwZgZ^ypfdl}C$R<}(bRhm8=#7K_m zb#pFb)Ux9Yt-&tiaQSq!q3VA7u(FX=mZLksmPc=>CyVPEaj=W5j%k6t%GUk0>iT;9 z<3Hv<{`UIUf9gN~xSk~J+nqn;hlllb;r;ypcJJAPb=z(kXSo0Kzx&TXV7ToY_-G%_ zB?^9cFD*&Xk;FHh?R6s@K6EtfU3sI~Q2Ri+f(CI$pC5*_9vn~22Z3?`ck$s`RT>s`*uWSzjRo9%DC7iAlKVOBEly<2$y{bE<%{q0-qmoqrV zh;s9u`LKC^eVNRxVWamo%z6h#>HP5CyUluIZ*O=U*e?w_824wJt;E>1A8rjn<-_OU z`luSf<;z3nx9jJ)s@%g4wWft&7IU;73DUWz`t(G)ieo#P6LO${{z( zu1j{>y80ZVf}t3;`aX`hUwr?W>$7Qqmp>*h%B)Etv%-w(9`D$x>Cvls3ZgKf?DkGV zs^%QK+ijX|`RR3|y>s*W)z0B2ly~ibop;0jm)f>l$U9apShw_G0SK(+CV_!YTBTlVdkg6mCL*^xi2Ag;chEVdeML`;};# z`?_g!_1^x0HicDBmkPS=0W)YjJ1kTQz=Bnn*XJHqRmOwYof|Q#G7hmu_~`T#=kVum z@X`77c9eL^;vpZ_pBRrZ0?C0}1jidHtwe!U76)vxL3H~GC69-2)6COznCs~`?DXbs z;XQ`+Zk4s6Z`IxU?y+4D^Xd_NQGO_5=#q?04s?~z)BDEuJ;D&y3ov@fgS|}_T7`Gn zW>^`mfd*`=jchfo?_Hs_ai+(~G2Iqyf+@QB01O87O*;Tln?4&abb;Uc^;@P;@%ru6 zJu;m^F4wLU;{`vMw|qEXR*ik1Lz5!W=;#d<+xk{p_C}tV3|OTSE5HvAnI1_wHxlp>Ng#-hOJ>%$M2+yQmQZ z<3K!YJGWOlIjz?I#DUk`Iu`HBq=TU>YZ|CYk`H(qnS}*s3 zGFOoc4Z5@4jN2iU{3koC)f=aImJLLpn?M2vYMS88-b&xo2DLBw>1)U7oA0%^3p7!A z$AgxDd0*n$uV<0H?`dv6vpSB6bpZi0?Pa?GWFr_CoCPyhzgujNhgQ*0Hc=PYj&biz zpB`papbJiHrYcP%hI?tu@(R!CAv}cTdOb<%jvl@9O&WLZ2sVaiHTU zb<`yd_-4(_1(wIj7+vzp9p(|L_O>>87N-mo6p@@Cem#4sx$N6Nvu~!)g(mhc8-%FvXIH}=l9`K|E`|1jP;e#f11<~9UOV+P?= z3k=q)vi$MJ{o9r+9%J8Gui@wI92T2UA2cb?ts8nb?i^EC9^Q9RRS|BZy}k2oa~v72 zh`~%hY4K+J*)h=5qP+@8PKSJGrM-c}m|!!UwJID}bD~FavHG-n>O9D@9`sH#Ygix1 zZjgJy2sZ?&4L(rGN;CFobz3JQ6BBT-e3teBj-uGF<~P=7gKV)k!yy2LV|H#|G<%i3 zaSXs^FtzFG<3qjLhi{BGx(|jBgPdkBwbKV>BB>??8km$51Nf8?T-Q_Ux!1iyEiBa# zdvuqb(_p9qdxp>Rs#4zto?v*B}0&{`A}a!&N_C zUol2~d~>tDZ=LY6nC{=-R68)WUzzO*ppW7H-~G4$iJVaQ@r|pc9c5jFpR|k~%xYTN z15xxh-%pKiT2Bt@V)nyMQH3n-w%9zs8@e5ax4|FeNmN<56-4TRNcwTlgX<7deo7X# z$Ki@-PjhQ}aNi>E5+A0QRjz-8(|Q#ERL2LFGLjHQOe$s z`M%hQIjT>)f3cLsf_-D}*sqR&xreC*p>Yg-Za<(BhPkT~k5kInopbbtGZn+LnJaA! z?DjXVPuU@zZeJ`%9GxXI(~=Ei$tMkv=i9+odss^hlQ~-U^&7dHZg9)Z0Pb{LI=`V^ z_1u2UVaO#>5x7B^c(YMLygiZ^dT4(t5Z#1;hAaAjsAR9p*CR_?kMlWhOk$Vss@v7sZA2~0v)1zbE~_nU_q}V}_r9O~_;zr4C5~?!^4D|YacFt1HblHrel9{p&CPk%CH7n)-Y2L&&!p3^R^Nnu|Cmv#u@vr zc(=Uvm{E)M>NMEh^C#>A$v9ZMkHe0Dy@42>B{Mty`XS97@UPAJ#eVMza7hnl(xe6> z)X$-BO|!oH_=)S6-3P0aJMZHCymzf%f7REONvw*fSDCcu;T3+mk<4XrI?%($4nr-} z-2d$Ncv}?B?wO5ayD#EUG+kKu{eP}I}#v4a@8@PRVbu+U=+G3M%gwtkx z`^M{~F0H$dZ^JG%Ah`N2j*!eUhJXFCb06+KOadeTcCU;yp@)@2V4&O1x0XWCwSfS?M_){;$GNv9U42O4J4XX^rvd>+$4x5)|`(cgY=`Dez1 zmbHi3#t6kXvaK3HZ^6J}W`Vuh!QJ2ocv+^ax|V)p?_Ru`pMU!8-~Lwr>JPvDyI=C_bziG*E!WAs^}6;- z-_krqVPExmE4wCQlVfT1<8fA%|BL_jzkqvdn~$pU{iO(UctW$03w)qXQRe8Fz+v%$ zx;xC!h#{M>t*gRlc1gx|#}zy*FV1cKYzF7-r12rW%7)qD{iXTluhwX!0VntaI(gm6 zfmW*kt5-s`&$qft?eyQL``TT{&tLbYwY8wGo$r`7XUw)HP&MCd-YpgyGSs^Jc#nVf zv;FxO-*>_^yex2M-#yU{(I@lnhI#imXKoxP?+arD1QD*O!)G>|ReT$c##*N8dHNB1 zwN4+0?>l!JjH*JncE|7*z1uwas$#?C@krj|l6etrngc5%++lzWwyWHjYmPf>*ktZx z$??e<-Sa*WDRfu4k_Cu^C>pzB9;JdoLx+3S-ratXCtC%^ z!`UOleAmlin(T`)XMXZ1W_Nq^m)V=0(WScEkPh`u`Dusy&Rh#~0#Y#5`1+v**~&g? z4dia;R8mcO5vaI#Z@QI*`zm9rQKD&geCK-Fu-bwN24ou{%hEe5?Z8Nq*?s_5Te;Z# z?k>BoP5N5hB)jRu1R5)Q1Y5vb{yrej%Z^YX{dB`Jjzym+maUYzJm{fYW`&*&X1j&^ zZdtolzW+X;O-H-;iWtkv`Y>z*T-FU_S~lkaxwK43vr%Xd)owGZU9(I?-Fn{1a(0(H zOVc~8L{<62c^ukVS!}MdwrqL(5xIkA=Mf+|LP?*_i~eYzE;oa$P4CjSAn%PhC_%J+ zH{Vjv*k<#9i)(`@104_=4`X+Hi~SqsLBEiVS**cO@}xiQHr0jkCfi0)ciB6TmW%cP zU)(F*nCe{Az+{VrfPpSU_B@qE8QEwfjQiCNYbTaOnS{b~iM?&I5)GSApQle43e(kz zILKRikPAAdH3+Xy6R>E{u10=NJ9Yj-CA$-9ic z-{#Sk%%fesy~`iRoDW2)yVnN1&xduD*?^m6t!5M0*jXE9f=|zt;MgVD5kvB*Iu3aM z1xBbm>fT}I>O6hmvB`s}`0(!fcvl&)bv$%y>V?&Yf;r4!hi(uZHZdQtOXqjfj*6(; zS~^L#QH(+_Ce#&m7KD& zOvLc@NfhDS&!7pL$0K_oA(olIN7rsr+VOZGpT$7f%uX-1t@C46Re}?}rZF8Wi~H>- z?$1$es`RmiB~rcT9Cv2e7=y(a0Bt~$zcRP>K@)iT08k#I&oOGN-{St1L-Sx1`(_8m zN!wJZDM!vXu5BuM!Mtl(+!-Gznzq`^md0c+<^(@G57`#qfn8;Ebyw(ae>W^!SNSk* zMjHv(h<=z(i%wt^oE#JxZKp`@vYB+`%1bG>wJTA zp!fUt@CL$+@P<1`P&9*DKEb91xtS(?b&hgiU2FSO5yDj&G3I09vg~EGHRs#j-rSbK zc(on4Ykc>GIU9y)-CK>O)SZr+ax>Gu&iD@8gCw%#Eg$`1+SGeyZ{Iw>iD5{oD8Pw{P5r!MN@^T+h3;Z2Q=Y z!J?Uromks?&-b7Fpa0!|40fAwvF$Go49I@xwy9<|txRkaY!TnUTZj4WpxO+Y=0?F* zSb#pt+WnnVv}OQG<-t@R8}8Vv`7oo}*+Dya8IN-Pr0effkI{btuWFGfHcDlFDlg>9 z-hC}wc;;*GF5!~wUXl~t?qhGd05flUmEG{Dnuit&Ux?p(Slmw?=jffo1&#d|u4w!C zU>AnPy1z2dwavxhxtpB^Bih{@ZO23-v^olJ|1_>IgNkF=^7Ak=^%dhJWXz73Tg@S$ zRz);}d3@u(j!^r@tgrAB`=zYBQ^(}1noO5|{@>#H#l787W|$V4d@ZZn%Ge7|!sxbA zkX&Rprgh7pnw;{gGw zjmzF?a)Y^T4?BK}W+?`?hDC2%yO@}yhVNal2nV0&u>&Z&ZR9eA9wR)I7v~$VOFP32 zb(Npm-Sz78pHwFxcH-VuWQcHKi|4$a25uzAwB6P(V_b^4zjnOEswG)h9>=T~{JjdJ zcAbyI(iUi-S?9KMh8w%Vn)Dh!d;gg8$bAuzpVqDGwrneyH>*I3=!luOeACe!c5jbr zJ3=d@T`=>Ko1vig!7*{I(^L}Uz)IDs^8>i8se*XAWMWk|tc$00yLUEA(=44)#Wq{l zj)(5O7_4PxC{|xos2%JEoRQPV+NfFu(B4lU5x070hY^jkQ(R=7U@^!$3JjW^2+M1el2aH`k&uE1kN9e!ro z*~3oreJ9;8*tg6*kHD4ZK#8~2X1woSsWx=OI9$Cu&Cc(KezU4lc)v8pS>0}P-}v|^ zhHYgyf5QDsmtEKX?en*P{A2zv|M27AJX`<4KWpRt%V+KET-c4*%KUPV{Q6?H9o#Do z{TJ^KUvLkOV{%T}Y5DSh{@?sZKvg=NR)tAV>wSfuef$lEP*0AdI-uJ)n&S3`nHA)1 z;hFHxaRN1181K{%@||&#FT*!@d$v&~s+Prrc=nQ!P{F*p@|CoP4m*k-FdzA&=6BWR zenGeH(aNaYc(1#=U!BLkKX)c6?7a(h(~lfI?c1r2gNfQh_ zM@s}YiWWd6e#lVJLU_6S_&VN?tY+25w9akDRVK>Mz|9S50m+;?@o02ajK@KL44a=7 z=Yey&TBMTEHErwG+?tGdWjF;rAShJK3E1_-6wFtf93uS5OA3S80?E``8Gbm z@9ODT&9*ARdpG^){pqlBO0?@GmqTq2e1cBm0kfO!f|`>m zxeKxlMA$0ep;5q)4f$<746re6l5x6ygH5=z7kCgGMqnTcBtRpry8u_hX7yFS)ct+s z0(uc=0}kb8Juq?j{YjR|-Mp)s8d3xO_8xrgcpENXp2VBI_IOJhhHT7fO=E6@mW?m3 zV@`=(wF3H-haGf18`rUs8sN=?(#=TA|N z>&1E6deH+4?#*n`om(QSykM5maps4N#`Hn|=l}6Pg#OyQh5_Z~){CJwW8PdHk-)Yl zd~|K%V5SJYO(xkdwi7qAY!3R%=UZ0?muVQlmia0iJ#NEE7S3EB4CzyrI$7dGF-x+B1S#aMI|5X3hv8?cRgH zN7`f5D}4m_U1mm@sm<`Z-Ht@Z-l+peJO?{tmtM5 zZC1f)v$}hRb-@hJuM^nMAB>W{`?uc)T!+`Il;17F&o_L(I1YLRy{LLEn5~s=2F})| zf8iVyT4fTf7*-azuVY4QZ+{PfA+RxnN?iw{)nvmM{g^E)2<5F}^>(+2BM*B_Tr>l#ji&HX#PCu#y${oFGqkE5YP2CTGt@l|Rc`P@<$TWN(BV1v+BcM$#DuVlce@bMxJO9E8yY1`R+{f~D{V6un`fk#e9}Rp9>4yRP-~8bgC=4zk1KO-Ue3mDzS4 zHdsBxh$BoqK9j+MxBxfM_PVHGWzz$bbHL=Xro;?gbDn z!+yQK|Nf8pyKf)A|K9)RFF$|k^Yiz=tM99omR`AP@2c*d(bsTpg0>HeVgO+v$4UFF(d+xOUIc+*E|2 zqxj>Wq;{9VU2$N5_tooOIP(8<=ehuz;14-4g1$BEnxNTC0y{khJs%-wt?PgtuL z&ogR!8qHgUI6PYxh)~feU|1yZAlj@jtgm)j9n;WcKwtonK!b3Y>Ok+kWrQ}(q006X zc{#1K;#zrrC7!;%dzHOE;`w79cXlR(pOzS(|R--E~H?)t*T8l8y44seBwS0K(p4e4`(kw#O!9~TMMgD_XxKBd zth*7@6J#OOrS>QAY57BstK$oHnpt+}}xaGwefff!R5kz$k8lCI1V^w{P`ra1SX2l8z+|AVA zeG_K1^!de(n56juPBQ~xh{FF)3|SAill+;Z1KPRoT6bvsA>uUMQ>k6Yi`9K0I%Mu=nV1m|&UVlXrK^`co}* zX0}wlYRl71wXJl9u{PwN8;bS_L z3)hwBJ0kQ-JFL`!nZ0Aop}HXY6U;&cO7R5-pP-v6-3l#@U_jLtljzE2PBoexhTM(e zGMO~%RR+;)ci~!h9#hgC2t5z*rcf<&x=I3Vc{SCI2?PAibOS*H4rgyUWN-NVY$xN; z{;csF{n7Pq`DzWta6xZTeVRFI18!!@W#<=6haC6I5uy->mFS{*n+cC;x3!pN2hx)G zER)3}Bb2w#38ZZqSQ4w3yCH#MoYGF7oi~rpw#ak}`^I>1w@_>c!&T*{_ZC0+p}knOJ&>ah}R!IyoMY_457Tr*~)5aHQF)#1f&o8A^V(4WS zV#^0$K5ew}Uhcwt1J#flO~_p`Gmp|qZ6n#yw&7pMW&5M~blnph9?kH&hZp)<} z2Uh!AaA%#Hp}siWIn)R1cD4z0_o`^WIl|FCE8gwnTU7RZ^e%mT_~Xact;5FJ7(-Zd z(b1h2Uh>(-bNH+0IT5t;81V2(_U3s)8fYC4MiGI&-5+h)nPkd`9Z$=Gx4K}#30oz; zh$-DB*6}b~R3XWbtPz7Zh~z_lPt}GUv3Ie+IgJp6Pt`m4!7&Z&{6b`tF86l%L5D;W ziM!J|-@yXB%fhy{HO(a!m%B6Fjvfc=1x#uQG*9fi37c8_p;z)uviy037tFv!ypv{1 z`CxBA#0dc~qjfk@k)I9b$9-??KYX9kJ|i>Qmn~y&9)8*gO1qni+S2kJs?BpJ27Ad| z*D~=ki5Mokiore)Wgh6D*D=rDetKn11I+wV`Io=_{ThG#uYUTgKivQ3 zr~K{Jxm8+9#c`;1qupq&DYY{K)#HGQX?|*_b-S6~Y&>R`-+Svg?0BDl@89x&@lXB( zNM^g{R4w0cv=`jXhOpZH#PZcKp_?{3my2*gFh8v~){xI>qQV|QZJXRj45-GEG05zS zymY?NJ^C(8-d?k5VS&Q%wp-~?TTjm#2ir8CRyQ9{_RBPDU#w^|-6ik)l?~q8_tVeM zy8MI_tKI!=x;Mf)&Nr^MR&sNEu?f)GsmSTBMuA|%8fF8wQE|U;jN36*8*&DnMlZp% z1+NIR>hh=RI?UI#hBso^F1IGbS~DeGlwI?E)J@mmq=Z6|r|p))l!x11Z7{hUGzJZ0 z;=1wv-q$BLISp%ZM2n2n2G!DtbIHtN>Xiy(-@@Vhw>+T?rup128W7fPQN;AT}i## z^A&F5nKMyGWMxE5Ql0+hc1>MGSOiDMQu%cCK8G#H6Z-+*2)0I|yblzTQRB({PCMEN zlz?~)Zxtkkg3Xw$;i1>!{juZOl_Tuc^{~0Q@R2v$I0iaBWb84mO$)X^m~&f>)ouq2q8PUX62<+U_;xa}N1o;9+nW3Zf0ny3L=RlAlial=i_La?jPhtrOGxI1MSd4}Vl;ue2{QE7anMy>7buqxRKq zZLXDrGPxedSa-Jkr0@2+D*hy5-@CKp+b=);h|G&Hwp7{hxu=JP9Kh?%h=}BOynK zVm4)MI8AUw3h$0owE(_-Y0B(^J9+r{P`^>?EONxYr3n=ks9U*0UyR>n#BTIWyrFjU zp-%G$^_cldM%x(J&O3WXF0=FgEYICpbxZTyFWzqZ+UwfAv5&);pjmC_fC)`UxrY;~ z9?_W|zTBs|VdplV?=wF4&SeVY&Um65tO4LY(O7Eo>3F&>ks?uxL4YhU6a zi^;p&?H29TK3r@xz?{>`zF|I+5&fb?wOn*AA6DzGa(R2w&^7{a+n?egg!bka@+zDM zn4Y^s5}Q4rPiB_6b=UC*sLwC5#t&eo9!gal zs0?=i;d`YMh_Tw_4#nDioJH5Lrswc^K1DMZb}Br#c3I@BvetM;-^qj4a9{I_@8#Sph9TW- z!yy%{1q*AFo0W(yt>xZ5hkY)doOIqy8$6-Dv-j1{Ygbc8v&GY z^kCng^wE7;Mzab}^5xGl=8sbHFhhbt9%M=egLqhrR=^2^x7y9%z-8CHUikJ)^1coR z-;b(;}boJ5>K;XOrB!>y5~>84+pmp+hDItMR>DDnG?cxL-r#^ zzMAk!OGJO{@oV27`I4eqT#&Sjk*{^%cVX7P7Yyc1>)j1^9{!Mf%OAu-jXH;Q79>0; zi!)lIo^Ktq%lx3qy2UZuZF=>6QEsJn&Qsa5=VRu#j5mvtJ?ZVG@=bV;2n(Yh0fWQG z*$an9ryf%_%`~*UWTvXM_73xfZDFB7`s$u%_maj*lbcI`k5ucvU=N~Z?&ZHReK-%z zC)VrMfW!I@dlQ{yh3#d1Oj)`$lwRmDLtS>7t+qi6)Ex(9E_bip1Pb)ox^cYuy--~- zt=H##3#}S&bGIOAyL#iqT=JvK&C)(U!>>w*7-;sUJz1adsp<}z}M77&EDtqVV zF-;}r($iTS)9zQ(0|(<}ua)B=6m_?TeXjB_P}vS7!qMPy_a_9O2y}0ORmUT0u^cBN zSr)!79bb?)Z77!ov$prJps$U(0K073&TSlij&Qs_+aW(q-C*08AzOvYYUrN91Pj<_ z3P{uq4fxQtf}+cWHiv&%oK7`Hb@p+>iIsK+yQvpsJ?yxCmOq@;d~5DXG|}yq$*#r_ zqOKJlv`*z@TW9((7)sUAWs~Yq7*)DS5AuAg)#HaZ&1LrGI7L(wveP@u%f`F+6&3<* z-tsp~u##3n8;kZ7Hx_Ul>`%7KiS?U_hk2lytA9SY)D0u*m;Uqx_MHr1+VsmKIR0Xfr0gAAe9o8k853k*R6Q4fCS)o&L`Yllq^>UdL@*Fxo<=9}m=7?HTukmS+b^GjrDFE5WcysuZd z^MOuam=-*&tG8;~5j7&h3R^V+pBv6s+w9B&ye&e~y6X7B>wCg{G8$aldLbUDPmck4 z;8Q(W7j@!EJE{GND^+`={&^tEHVOrotU z$xb&JkC*Z{r#^curkY?5jbHr!(exqPTn}>5N*?j}zajpoRxUimwsg^xt36HgFjTkg zY(IcM7*HkRxxfjP@T|P_^!1_n!1zV$VP&wf{Y3{ZqFr$l-_U=?eQ8pw#@ktBgQwmK zOs&Rc_y7Gm|G|9yxaK$2JMCrn%wA4)+VlQ-!RbE_e$Ml%pGA++)A*rb9#>w=tc_3c zWeISJMMs7k1B%AxBBwJq{e*4N+0=pN7g<`j1I2ez2G5oqV85$@N0v^j4c*{>*7hF; z2|sF@_nYjOkc$t^?_&d_RcB)J@anMMO3*&~bj#qpX`T4LTK`kn%QXtS?Qja=MgtDJ z9`$VDeV95dve-X#e_H=%iGPTDc4c1~^Dl+JwD?*2zeqnS{z(06@DJ9z@eAx?-;5>> zbBF)h`^Wj^Z;!{neexe%`S;i7zpMJ&`~2_o_0~W9z>M|+_nV62*!?r=Z+QRgxPAFu zm$UUqFZ5W#vAw33TlD;5AHOi7JPc`(K7LT?e!kw(qpzaY<#*0+IDh{AuYUXe?GGP+ zBmHml@mR0lpue(o{%~P5>XQGz+5e95d#9jceRZFJ;2L%sDHP1SuutEGBc?Qt_hesr z(*MOj`A2{lQS)G4XvZ9WUv-|1;0F8?SbP44bGQE> zP}uiXcYjp*j7`NEa?|v`t?1(U|L!(`_x`}SMGC{a&aZLZ|=Rrd> z5TKHUCrFz_@jS(!${{u(1S)0cl%+z;Ip&MFpaFM z`Q#Y0mJzT8e{T|bYh>Gd@KrIo=`fSa58NM1W|9k>Wfs=nRIZBknSPk)cH#I9b{qEg z-vq9n?~JTHtS{hU*R>&0rUa<#?&i2(P`LIjr#k=-p+M3U{w}-*r zWRt_&+oi}fKo6fT|;efN%k z-(L9S8t5^ww_hoOhj=*J!=J19|H^I%gsC3xgl}%* z9Mp|YkPX*uj9D(j%c^A6O-{iKx){OEvValm;nRxM{6YBlEw4twjcW;W*e;#SC4UnV z`Dnj=-R`4ZRpLAir>~M=H3S;|SMr}5Ux-bOQ6*h$&xWFnm(>>U?hstTUcVQI_rIrp z(ZS~U$~k|;+n@RIH#z@P_rGcOcfh|({tEtQh97BvDtoeBbgJ0D$iCB97fwyN;fXOEAW`)L;1^YXWEnZLKb zd3=E$6@mD7e4fGLWf2@dM4XyAus*E6nY}r?5bR$NV|$w!JUvtK#t?6VHc?2Iger7GWL@%rr3ot7 zRXv`F!}_!OjQ(hMO7J82K|8tfIw+h|FlkoHa-T;n;e@5{!SB@)$&2QxLl zJQ_k8f`nDOv!UUEd`X|wurXpS!$J-rhApLOXKb zWs_xh@ePl|lhyK*ou>+5wFt^Xe&;$)xS`RwF%IuPNXX-T1x*0KYvbl)46u zO`3#f?N>;00}B$6bhW#BQ_ja>N5}azyBvpHFp6K<1tbkHLK{XBn~ z`!BQhB@7mmn8h83z9k=KUD%!D7-roawxW)lhV)jt61yvCTMir3+os8hJWTEL5T`Eq z!*}+_>z6z3Z@>IEzx(|2kNV|xUAbDrRLL=Rk(}_Z3?`5BZ9Mz>#V{U$<+sP-_sw6* zu!tCMN3FXpY#dg}ppC~og0H)(rVn$P^`4Lt?1aE66 z_9c7x@vv?)1iJiLxPpm;+~wZKJvobx{E%KUD^diMoA-)eGKO2S_K zun=z<*0w<#o}Xe^rEt7SXChoG+ zN+YtYZ=<0An(}t{DBwI|-C~$>ScI0mdZ!)6m3Er#&x+}HH!X5#m>W0F2uG%hu9f5} zw_4bry03m5?5wVg)AwRFq#$h4K0ffP->h=qcZ5f`5zUhZb8y>mYqyvI6TmXK11j-w zZEvK~Qm{lkyVJs3-h%|I2J)5_+PVQM`nz=0D9dVlkl(BzhM6Oi1Xf9*h8W0Sc)rUC zJ32**_RjT<^Bo}IhGGvf(Jq?ZuZU=N;{>TJJ17(R0G26hd{N(4yYb{O+PhufFn-Yb z6i6EK^6^FM?w}!P4iPCkUU7V-hsUHj?X9_JQ^(UVVN?e^s3rzz#)SYPWbL~m8q+m=XZr{<^|eRz+Yf)c?rp1@ z(ZeCy5qf0@C}(5Ke1==rYSo3peVPA@fBH`Vcid)<+>8f?y9>QxVz(XOO6mbt`_G(z z%TO3#eS!`zgagSc5-hUObY^R&!?QM~gaDh@N8^YR^LrJ0jNY4sEI7gnx<7fGtYo?A zh5dw^klLfU>VoB7NzCZG@R`^1hbxiyrrWAIR*%Qgnc?l{$z226VhGKwO2kU6wDTw! z)~*1$*d~=QP~DaC(`sX5b(_Db3WGc*#?z0n+rt$rIR{8%0NLk5D`VA~hZ{32vH)wz zcz9P?7KR!qgI8LdwYGpbbC>0!JJ{y4VWtI=k_#%uoV$SIOZQK9yn7aL#qH`FZE^~` z=MT9XpbsL{cH-lwhLykd=Qj(_S|EaM9*iz8#DiKW?S$5==jm&WK;Nk<9Y1uZ#=~#{ z!@AY*A&QEViGp}I)}2~bX{|M#+19Nwv!KnWHh?i>sY95$JM=WyYFu+n^$kTvM$1Ec zp2L;-$#L-gSLgn@M1}c&(X&e~RdlTF!)hE^*S0s}9>sL{JgKd6-XEKXxjC9NxchoB z6cM{CL|TSr?s1^fBpaR^ooNrgz8lgormym&Q=PBg?NqnVy4sFI%X*8hed{pmSTUuI zaMH%U2zUymv{X?l;~2vXyY)UIu`^mV!s<>$pgk{QG&J}Kq_4cBVbfl(^P~!!C!=CP z-R?WjA3SfuaxlW%sCymv`c5^>7-e1X5hTNG%9fq)O0xqV(H%^dA7%}drgP3V8XG-{ zWs|se!%aY4I38Bj_HOtDJN+Pv_tJ4tH~B!zBa$$R!nQG##h`6g!GGj#T2r?YX!Hn< zH{+#V>_@YShM+i6tKD2h4Dq6GUXYnd%9c;^Mk{EUqFJvy#O!2*+-URxWm$5c)3Q0t zq|V}UKW;yk&mU;ZV}b_TKv6{lloCV&FaTEA#@?9JTI)8fwO+el>o|jJ_ucS{Fk|6?s-5uA*AM?6@_lMUX{_68Det-SN zXZ`M5E;AvyV~>{P2i<+o8RwJE!0-si7$FiXFLVQq`voHA(f73?cB?8!s9XJ*)+oZS z?ijt>|JDEIKcKP$K$*#Ms6X4x{mc6C-@@DQJ8HS+LLTxn)-OGObbN=o9dD)&V@OZ% zC&t4&^B8P1{4&zp+H7+*SE?OxE4`}C2bQde?ik0+ornwvnhpugW96s&san+zzd6rsVSDw}o;RUB0>!Qh>l}xq%u+Pl zsaG$8Njr$`d`JLDDx%e~^VKC-_u7kNT5%jwIH}S8_@U$Uh_EAE`NMfYh!)ZyU?De# z?DX+jq1(sT^c|TuhbirNAh%RL+fs6ASG#pMHiYnou66|aB~rO3@$mk*3w z{wuqG-cZ^YgsFw0o%i-GV4irbJq{3JbhlYpb5D4wj!DJz1$#E8*w!ezYQx^MZ;IQW z+~|nbq8-vKre#O8jsY}hs!;UmRq9@R!nhh z!eNIzJ(D(tqvB1wn(f2X?#NyZ&C>v!c^-uj^)Cm1ey_07b&5EZeQnNTn{_T+;CW(|_`hMWZEp z<2YGc6ylcNM*e}{U-VC;vtRP3#|Lbn35h{pjhWU@_G&VqTZ>du^Bv@&<)ZULWbuXKH8m4-T> zgV{y*(f--}1YtED=;5aQi@RZ--WLQ8&)U?0qt(UnMA<4da)9j`O^`zxQ@yR!yLNLR znD+)FT--#k+s+PXG{${#(9L|ePFBTXyD(V0$J6sR9$wWrgX!mcXYsvp9fjPhCK}A; z-b=u?IGLMGSf-rAthdNryKR*AfNoATbb|4N<#nDy?Tj}Vhc3kz>BD3&s~FU9-x~q2 z5i}26w1@U5#_76HjO)AKt7qu?BVXi7bZ7ivS+-Z6U*hv~*uk=Qf#VW;C~RR8vjMF;VWL z*Ls{20o=o3W^!}>HEEs%*zLAd6c6fq#&nS?jQ|D*RF3&o+NLH!?($z5lU2r)WI4Dl zLt&oSOS2N2{@D2@dOEJRU}6 zQ0EuG0E2X^J$N!}TRE;>OfD@|W(+97D(n+PEt0`|YU&O9DF`PXWZD7@{ z7-ac+RUYmr9ID;p4fm_<=)G4V@BF+vuZ=SfYB#FG)dR$s@tknua92*Am12;k+%d4O z_g~?7_;m#xV@RMhQVB;ui+(C3N}aGUGj^-8=w<|r-o=N8ja9NhmyK`|MqTzcRK+p0 zI=<|_RfkPut`|-}s*|~=k9&#k7Z>DHf(@ZHJW#t`lBGx3L4y?=-uJD?o9*s-tc;_W zg~L{iXRjKMNWN&li59~fMmIY=Htd+S7kC(606bZJcMm)0^I&d${o!@v(My6@eLPJI zA=r~g>t147t$Likvq=~o?UT28G_4o2$@Cdg8qAdBgRaO{Nkio(#Qf6zon@;bE0}kf z**xv~y_5TRJM$y6XkF#R%S+ADooYK)*&})hZriNK>FXot8E$#o_yV*C{gqZ-F+&?_ zO`C#>T`%sy+YwSuN3NVd^;BiVts|-Y>TY^P4>6 z1e!h|V}sT0?wwvK1bA^Av>P-OgofWG7zq?QfRan&AP?>r;t{#(DD9@Du&F~;ZcP#U zYO9W?akn4i6ZaXcz##U4&hx6O9ajW%Jxm`+4n`a zyfII$Yg27)TgUV8fBwJw#{zYj3hoOC=H~bT@o5Z(9J0#tAi;6M;aR4pNgl0;oehC! zds%x4%uld1-xymQ9M+mxFAbxgxNgh`lx>HL?T7g(rDK`ev5iJHMreg&wYqhnF1w|j z`T5H1tnBY9%AC3FqnKr`vLQd7_V&={=X~9I%&|+)V>&j5p&6drysAHL(2r5E8b?^I z&9g$RcC*^WQk+lZjh%E)7T=E8J-h)pF(f@~WO#rsC$Iro90@bY!o2bqJAN3pwvmJ5 zG~cgnUo|#csPZ^`x<0-O8!5uVmvw{(t6Bo9 zyjy-iBks#^4-D*-w`7C8ZTR)sk2h<$Gv-ivFUjht?=(|YM~wCA_8t>p-`OS`rz5M) zdz+u8Qay54IQN?2RE)Qy9^! z^w)A$BL z^)cm|?~Yfo(JaAg(RKTq)@2c}FOgRSdS6g4dp6r>2%=JG6=X$^>Nee=>*IyYjQ7Jq z(mLS|gn1Og?Nj3c_r8|Q*mqSplRif+POogTTPk~csB5JLD_M7sBQvdS$I;%yqFf{Q z&V?}>Hc;;H^XL_AHNiFQaj$t6?3n#>xT)IP?2Sq@X3?v{osfamK$G!cVocX=c%dje zbe!5RX!hQir3^|iU~NARGGX+Eev&mCHa>ppsRWH*xPRh!!l)$}wHF!+11FK-U~j_V zvMptY);{hFk1zH5B%tC&<9Dtk^ARWHC` zp@N&2+W*x*`;REGe(9vE5kpw&uhLC4>`VDjTS9g`#=5|%NzH*MAicaf;2$h&bIa~p zvfKDYxBx?5y_5S%E9@oy1|jygaI`zWlLuj5e`JTx7X+AN10wnsjGd~2F5K7V#QoZ3 zSED|=sa4|>#VSbdX5%p4{<`u0wLf0*iTbl&+kKY_-w`6Rn`r zi|S+#JfBE-eeOE#Y5fUCW4p0>ZMs{k8}qKTIV)F(BZ=aeHlpAiv+KM3%{q;Rv{|p7 zkCB9Ky*=&oMvtSv-x^+`TSe^j=*DrVW7u!{__+=@o*F5@5~T%zZIcgL{f=xg&6p%arWlJD_v`iU)$^QLkV*ZrpXrsU#sRhNU$VxrC*DB!B8=WwtRY!l^WA_buaNi zG;Q3<$Z83mv$+$@iymDP+kHeqwvD!uH1IAxCTde5hpO8t5AU53wt603vccvEnUQAK zM^}S`(jF(VV$ES?y+WDePe%VNpQZ_>878A4UKjic0x`ul&2kZ)YG*6PWLI_1VWz4= zm#xjWk!Z&~YHJ*u<}39!*dC9E_Puxd@pfSnjrF;YXEcg85FG`1w-DOB0z9tQj);P) z9^)alU4^op9a?rCyA{|K<2>Fw1&VWMuIPu@bm@3lzudL$J?cd+A!ueGSgpc&Fq1Lc zFuE*J0TSf2ot!2cDCfRiO$p=l>m?l8FCJg3)6B{qz|AT+-38m~K}(jwLEZ8bxtlNq z0^oxEsn<=bQj!~RfhvHI1r?1AgsQEY07%y_Er^X9p!$(^-Go4wnf10xluVQ$_0Y>6 z5fAqxXhn0-$b(I}kp(~;d%C^CCeTfJz$x7yYwypG{o7yi`s3&S?=L@o9_QMf$YBpi33Rm&ue7EN9mfgM z&T&2-RJQYy@tEow$8(|8yKn2GIexIw*&xB)S6GxUY?A{>sK=>mZOH${KmA8gA{}w? zujR$w4)`R=>rQ`z zt%0GbbfcT#ZtOZDyjw-@_DRyVVqjFlUTz1ydvBLuL9Fg~z74C53O_CC_GpfW@8s}N zC2M;OepZznCV!8-{26L_3Eb~C2qUh(URmrNRmABSEm9uIc$UOi@Z zt~v%@X1DxLbnnhj9B;!^@Uge{cSI;Ubf5|lM|jpcA`CgqbI@B?@$1v>rNi3WX|Og< z^ov!u#ppfL4&==4fbZKJ!*X_e-N zNr*K(l-k)Pp^05~s#osZgKC@Tgjrk60IM-*=#)=`WaWjFVJvM#VBcd#_c#n$RE{ng zvsKNa+Fi(H=AH2OV%7B;=CZ@gHDqmie_E4E)=ZCR>vM!XEYz=UY>_?Quy*L89kvM* z6G13E`cAsC^8B&aOKk7VV|FGbKr~pVs(mHTx1q9HW!fAzO|;zXN0>5O`*={-PQcqN z2D$0ptB?73y;#D-jKuoH7=|#C^_lUc#AB#wT^u!rB@r3Qz=;LpY|Y*tef zcmbO!?E<0UK=gjWzdF43*7>8=r|w06$W8gV?TgiAnH&x*{xy_1<;NJ!Ie?%C{eTH( z;9?Kb076NLZ2ABSq&iEPSM2Na{wS=Xv6AMe-JfE#vG$ft^qmp86^E;C=kfBD__^`HMVf4X*VR;6rorrNxc<_eg$W7y-d`?4-Qj@W60#xdvYVV3zy zH}px~?#F!7M?ysll&{foj9I;^CSzN-S(KQXNBF<|r~eB8c0_5@1_M36dTky@TR|o} z8WHYr1P(`Av+axTPtJGsFU*vNQK({GM57E$`0jGUR=*3?+rtj%RzJ{JAAjccN6?Ws ztW*Q6>g}}j$==X#8V5UX?9p~Nef}`l_uBI$qISMkw{eRT4i z?4=rsHXrpcZM2XPV>{KQ7MOQ!D#>Gi2WPeis`_xdtGnZQ)P*_AW%0CVi~-0tG5qCd%iVsyf=X z_13O!9K}7%BA#BKTWBl)7ytYJH7wAZ>sA1Cb17ztu+2txc-t_t% z(zF3@EfP0vu(BbmgWav-9^K!`DJ$xRJM0^o0k2Mu?RIqDX@_H#H78&Pv{^+Tb(6I! z9@5@8^t;ch=Gyz#=gK>k<~{IP+c!Llr5Fbx?)y~-4_qbJI(>BH%F#8Jj@JAMPs|3sx`iZRveG1s+BZ$%Ag(RM7KrF z6COD2kn()1sIlc%HX%KB-#$&|hV+8HqxU9S8qG$&q@W}GAvHLXMSsAS&L?+vyQ-~s zAtFC4ep9y4h`!;6C|k%_X|xi&v2TvU-DzvZadyE>GtiTiD>TfGAQ~GyA)B=`YAH^) zXcp^We_CgG_%Up}t6p9jy>kTIe06t$fwf|IDF(0YPk3((BGFC=xt4t)R_D}?=HL47*4IBRZnkRvs!!LAmnNrG7U8uuvVyh7G>L)Ew!;}_ zd)>vx;%>Mvy8Uphz1_y%9i7z{y{qxsH6D_}1_HY<$r|Vu*#;DAa}JjZlwICW*d05K z&S}bRwqbGf_d9t6o5q`FN^m}oh_qf*v=39GyMe+qH&kgi<}7RHX~4n0=mU};Slhw2 zc-u4Nuk1+0dL?S>8gB!$sx z10K$RwbIzITC!%*hN;C&wn4YVI;L9#P8mDPhvy|1{ekPJ#?UeBz91u={Yiu<&G)#! z$quiV4-zd-%iV+ptknw^S0_M$gXP-5VYRo}+YNa?vOXF!hpeoNj4n>!S&%VY3lKOF zgu#1|n{a4jJgtjp-)UdnA4I_60%^e#%;{Sk6vz!YX+%SmHe6<(SdaSt@$u2C>Wld< zgw0k*ZH_4)4>JL+HjW&pqfPSXAnf(=@$Hw_w_mQ`{_*~A|FHkt&CJ-{Tjg}05$>U= zTydDeL^pRt5r!-Ck?sS+{ryEV+xK309#%N&F~*&M&}O=VLNDy?yM#$^vQ5^6$y%I4 z{xAQx|AE&DZuE_ z=w0L2#HH~Y);FCq?6g^J5A59*P`6xs&?jp%PMBM@K|J5NZyK;a*;8m=sjiJK_2;F# zt#=l!U%k3~S+l*3Uytqu`)jn+=+1_YrfeqA}iIQNZ5I2*T3Q<*7FnZpxi_WZT&Z$jzopZWdU zMqrrjTK-AsA5Fy$403Luku+#`o{*n8C;__UqymmfS`Yxy~oZYpBB^5 zW**ILqkDYi5!{W4KHiX*1;D0-CfY+yDmkb$sW=W`%TFRLpN$W67_RiE)d&1bn@3$W zPLgO@jMkdtfNz!|%=b6Nw6Vd#RXq^)S=}bXRQq8h`#UgUWu0KlVf)oIARR0ZgKfZa zAYaDf6#QhbR=8RXuyeSrvRW1-#rwwNOJVwcHD`~ufIIDU^LOj-@Bs(i34@A!z-}S{ zkqNRv)@IMVVg2p?d0nr_$~n1rIx;+xJvsWz!>*6+W8#Wg_V#Xk&Ft$lzyH7A>orErr6S#?EVESl0k7Y$b-dH7qc~mYswCx(oH!R#e}O z_c+^&&tvaRc*^L_Haa?}oVd@(KyTDE)uLZ{}h z48K^DfRU^Z+t=n{c!=M*vwhlL*E(AFeIM8)}`VeSYam&5*X9 zzn)bKsG6Z497FRaJUCM=6f7W!r|o)-(WK z@uu7s!#i!T@fJ$?oGjPv*0n{TUNwDh9l+%!5YtTNvVANWt4kxmIM|y5@u$C*o$>jh zailxiAnFWg+VhbOe*X^4+28AY6U^$i1m6z{s#fHb>?u3X+rO%ByOK)Tmwvb{@4iQS zKAyC>{EfQp?b-jc`^)=!3_X8+nd$wD|GmGV?|)p6AKw1K|M>jjJO9i7 z@5Z0R|KRU_{mp0m{?BWj{&)X-&mZ!<|0>>pi2u&t{`z0J=MQCdukG;FrmR>SwJT0Xl{%X_r^~1pEBg5snT#EXoM%+BTWwyF!>?i>`3xp6L7sv?9#Wj`@e+KToz#pTqz@M-z3oK#T0tDAL zlZ=cw5hu<$yI5<@ImYO{6$CtwkYd7XZ6GPp44^sxwZFgROg-j5|vVSu{qt zU5#E@FqJvWD?1?tDCZmW$||WTK1wu$6-Dv%i^jcVVz409g#u1vMj^qqGAITtSt2zE zAOdrWwJ4%G<6fm?A*^zQt@JZ_VJ`(qFCjgl7mOFm5)29ojE4t#eXG?VmQvNOnWyCL zSR|*85Hz`%YBSqP24yKEo3cWnL_&-#5`YLq5QQR`dY}1Je(Yc7I7?aii?8e4Q6k!w z1qfpk)rsY6EP)V7`0LBhZ~W=y_NUMvKA)dnZwHy#y#^h+E>u9MUJ^mVOlP`KN3p6j*MEbZ{fNY)CQs7KKhgyiI=(2HUgf5Gv+W21Y55|eH64KK zwq=Qk5*14s!z4p3!@ES7@fcJErNXsl;kLvQ>oBBdD&mw4l}f25W3)wUmY7sPoNBBp z*18G^NfA{Lv|tGr4;T(#J`lUE3q4z%6dIb(*U~FErFfw@YNzG+z6Hy<&%$d@WRA%s+AQW(v077&v7l{cul$|If z2x>K}ov5YR@pq^hmj7cr$O zb)f(_i7SB;mI%UuMgUYGD4OA2Sz11%-u5b`LZ83U;nbd*2oXcS?PTd{^Bm2L=k4iKswL43`E%A)I5JCTNLpaBMnNkiBv~_Mjn-tMDwxM;@6=|~o~?slJlABe+_PEj zg|z_WFY?(!7d?eE4v-1cAnx9wN&+uJ|P zA8Y>NUy|!xKL0phGJgHr_U%=V-}(2S&dXohx8JU^%jdt1FJ0e1FTeci-E*$`M@6si z{w4p_f205Uw_{u2(IkgH**U^0*}Xv{X8_0$3!}_PS$l(LWM49fn6oC=1?S<7j8r1l z=1oE{Rdhz8hoYoAMG!?5K~@^7x*A*cCik~y4mCAZ5K>hec~V5093@r4GlmWWZNoEz!F37pm|Sh$b+iIdvTMxqa4lL0T|}YzUE?8 zAc!%;7S=48oTWzii&cb*a^ZZ_b(Q;oBr+XMli;joGE&YLxjfqTCjA}pngC@XQ7Tea z6hSeQ3Y0@s(gZ*aCNf_u>-H)9?!4cIL+@|ZF6$CDX6o7>*;Bx#ub*FMd^-5km-ELR zuXh|iV`)Cz$53J6V92D0Pp@3N8Yxh!1F*~T7qK5zwJdg4Ws#OXmsZdPLzRQ zfHQ(ZR7I6fW<{}l)b4k1?mn4ENiWIRTTr?nPLWp7Ra^vod~yaIp_D>a(MQHfP8R8r z;t7cF+?MoM;FK%?Ca5A3`+y1qk`cyU>@mVt%Iq{os*Nfw2sNS1rE8_8NluhVy3EoD zk(g1XtJDcosUe(7<*JB8gf$Tq7-jwNrnDi6BbUoUb%-*OoUAV8l8QMct5VA}os<-9 znupoyD3OpRLS$gfsiDa!?II`>x^dN@&H_qNjm`z_<@2Ze z=WYJxA3c11(bxale>ji!j1TYhV*T|G`1y4n&+^T;+ppTwFV^ir`t_PmAL6@znH$GB zSrc5-OPjK(Pi8tweMV{NvU!Yf>4;g=%p7VUVw66LphBQ+&132X;7nJ!Gn(36DidWj z^O(vCKdp7C$aGo@WR?i88E+^pVWceZGdD~3rmRdq%Zf1JJlDs%jV_aElt?rp3R$Xl z-q^Mf7QigmD{_QuLQoYY)rgd^HJGw3+c~W{ukV$U6-|p#5SPko&9q7qeu{L#S*f~c zo{=&olFO!;aOWo#@!16oMf@eOmm{@;OnGDZT%FvhNE^fa?4|*BwDlR`Di#=AF03#n9AYFy zY;mNpGR;|9?ug4b-?^WnSI>c}$!yyyORu6h&v7h?J*Wzhn8++`-rA*CHPyDZOlagj zOaI9~{x^UGnpSeo!XuIp5ngJMT7}8Q22@n9db~+irj_3^&lKhKjK=ee(~=g!@_;Hc zDJudJN9hG*E+ns=Ub6C1&W^sx`BtX1P0C4S&EjMsRmD*ReJ``D8s1o}eR{eVBJ_5i zWB9RGt#P~@C4D}~R;TGwGF2((o$E95)D);|I4$?#35b}8B(=99SB_aNWR>s^iOw3}s!HpU%4IAM#91a}qb;H#h$SLy=`y{V z_?aSYyG|F$QE?_U10%Zji;INH;~ zD29tPP*sdIi;qpe;Fi%Aj1kIKhuB)nW-bya*@nN-3 zTps(c|BrD0?GO0yU3*OV`FnrsNBhRUTA%Xg z{Q2{-U*`3_T<^VptWO{JpH{zI@FWXgJ9-O>b$jaD2YvY9wzPWq#qsnTJgy+)nCih1 z0C=&w%@7uxMfypk7$%k~mQF;gtkh;Q#8&Y$F^Y>wE!C=q%%*Ugz-8rRa?sve-3n3F z-~(xrXF`Ffa<|q`FCJP?DrZ)et(vvONHNSKy)jQm(yS(p1T)r$s(E;}R8Mcps?gXi zEesKuSY@Hb$kv1^Etd4Qb;YD!i8m9Omk$_kQ08Jfr-%WQ0>%k!pjPa~Csu&a0y#jD zF+*0#Atn*R4io`s3LsTU3PaGvOtNNJQ<*`L=2a|ffMOo9e#hgBh6j2z60_K|r1F$n z(o!d)ZJdLXStq3 z_!xICyuHQim*eLhfBy014==cd52sfcnFvOwA0`Tb5iQEK35Y4Fy~#|2Ee-q7c9qOB zS<>R|%_?)B&CK1aQttOrP09JTS6@>+5v4pJ7-rK_I{7;CFh5UHRtJrb=I!7-toECZ)iLnLh7x^|`$D9vGu zu)Ir~B_e()CpXVxQr4w|R8)AjMjVUJIUyLrM!(NcVKAIxDXE#TYPDAGCQ3kxdg&F} z@=PwQGbmy~pu~h|heI<9>mr%88cx@kB}ikK$Fa2iCG>$fnT^M!LswviOTw)`c&Lr@t9N4U zyub1C>@s;Qq0Pnt9KL6}mh=F2A^JzrL>TAJML3eRAF8vdm+zk%$u^&391+C96` z;>eogUQ)7Uh_CAsk&q+C9t+ZYITT7|oWX}+hR`8Z86`#37^`xO=u%bE6T|1i!sVUF zL^JY2zKUKa&AOwse3m?voyA3@#56TPLJpe)(uiC12cTH9kk*Wqk%Ll|MDIjO9S210 zuC$L`(AhRtQWrKe40gomn%Q3gf@Qtf4Y|}j7L;s@Wu>i%0~{$Q_hg)r zckT$0x`*U+)hZwh!AfVhOv-qx-o!{-6tBe(kk49=sGY*lYq02GWXZ_WR7~|uQ_<&| zZv>*jP%$g>u2q?c;W!QqkCK@)W+!7mSegzbmMAy96vP%0FN{+|FOMxupe}%>4lP9j z%pN+XYZn#ILMk7%*GxB^t|LPvLtL9XgvGP4H6Bjtq}mZc$)d@#Qwr295z!0*3Z{9~ z2u6z&C~+PN@j<(kALOrvLi}KjT18TFP#}qM4iW4Ta6oLgW?LBX`@1zuk zi?#^O!*i*=7EWE3o)e44j5M)KP%|P=*i)-<;(HvQ|03r_7>X!%q@T+`ya8|7Al5g1_+cW2M=OZJs-J-Qyt({x{`y$MxNc zm;Ul&9Gc(!g6~?7*ZddX&o?>W{aTi4_wQ3LWgqOR;rKy5e~h>LTz*^4(p+&{+gP=) zNNrpHYFmH#*nah>o3cG;Bm~rJGQzUT(od!yp2j%W4|d$kKoLNjCa0g;B@do^K{%%s zp=p(+YK)p1R0@-zdX~+l^` zHuH!i>ug*jN}|};vTKf+-b@7j%2J6@)lCzd$>FJwRXf6^b^2ERYGI69No6#}8GU6I z!V?XEU@u&%dAWk86_XmXm$k@9DECnynGlgNlPtAbSLDfAl`SEX6X_yKST>4BiHcZh zNw(UA<6da7y@%adOEuF<>6-4fKJ$F@wxJjVSt=$MimE6{5uKoc262Xv0#&7? zX)04Zx%Mc(EJt|8US*_wMX_`JIF=m?KJP$%^RIFXZ*_2s}DnmrktIiCCG^>f} zcYS!MqSVlT^6&rKpz$vd>{_W(F1%oMUYs={s+g!VQ{g9bivsqBvZ_O;PpNd}d7IPd zR*0ICaE!qA2tQjxwTAB0_ma1g42Y$&SLH>VXrp=q3c83)lo2NhJ+kTyNVqa*c#3j5 z!((_Iw-M-b)|q>SL`LO&ymZ7&rm7X9w8yfp>eCr*vANH_YB$C-Q;$igHlY^Yw4N72 z?ATpXo0_z&JEttN3q=&MEzML+=tv}G8HCs-l@JkYh&vQ&*)=QKDJsNBsZ6#46)si0 zyl;63V;PASIA6lv^PEyg=v9T43IxOyDph&ebWACr)L6K@8=k7H$eN=u3z^0ANzq1O zPNBsyiYBqMVj8_|Wh>7wisHyYvP4#Sqq=^gGyEuy3HfI0*>L;H?I_lk{?Llo5F(;coV&NLfTC~pL}>;<;2HR=i4#e&t{L8IFFtuUtWb>HpTwdzW%j5vEBY5 zzx4eV|B7ut@`pd@?KLjHvZp`DEqQq-Pw$uc2YdY(+c#58`PScl8lQ4J{EE-(>YwV< zr{l-B@%U?fkTrkMq29mN$G+4TeERcz&GX&g)bq8sL;VN*^p^S+^~rl<9Se8E*cvXa z*>$xKAN=d@s$G-E@#9^l3lp^pL0JtHKpYD}8Ls~|qmt+bQnkG__u(c{hibWO6%3iPqCRbZp z>}OwF;-C|2kC!i+WfZBBl2DOCqQsU|%`pWkakS-X8lh~7WVS`Bb>BxeH5XKBRXO#a z{X73X)|o8mqCQwtl_iVlQSz(-(SS%1@I`vhV=q`G!;aVy^@i$|qPMrm&U1$kQc%dg zD16Zd4(Sad;y1Pj)D)>eml!4279Sx`0wJa#+Dz3mGpfB~-eityAKYJM4gq2oMUH!T z)eaf^IjVBfqiCY*1tsRC)|aKU)={`1`pAU zN@*AedXu$xAJfHsDvjr)Bw44Ktz9KWE^;A&iE1&bR#SjkT$rQgtjl|yFR4qk5?(d$ zI7=*-IvCz`52iW2b5oTf|;ql2N<{fO}5uA!<&F^^n=E!q@Iq>w=9;1Ocemd>BUAl;l*!0p`eqVq5oVD<~ zcPoC6pX>DB`tsTCXWbs;`o7_3dHXca_qe`mi{tJ4k>Bj?yZZ2cSw?;Q`#IkaeXyrT zi++;x$Ncm*^_zJ7tzKtu&f^O{ojyC3$GkjbjmxI% zR?qK!dDmzk0+kUJ%nTD&-PNN)ATuF6jutw5tD4A$Im{jgL6lJ|v^X2}NLw0Qd&SxF zbS@&wJj+wsL-J(*VBAlV5G790I%dm}O_^*mBDL9lQX)&HPg`Rg9mCs|v>XwVXG&7i z*krQGOJ-84XM~7WZ!x`f^aX`&ouAPjA-knh7h|#&Rgpu%lHz%4RcIMP$>OZ3lp>ns zVUj7mAS?jM<*IRq3e#W})v$IQftHK|O?XZuoZ8US2%Kn7?ne<)BhV0$A#!@ELUb;| z2uYU|Dv5zaQ8-U#rkF58Sp7*P*h4}plc9y3ZPkd>7SSc%K&5z*nXKhOWVEUDA}pZP z(i3ThC}{;Atbek_D-4#uir8}{J^;lyBinM`&pM8T^rh!w9YQr9$0lunHY1`}Whbk*W)?oo7F<>T$-nzQ z1d6tZL;=-J`=x|RE9_!j=aKS(ek4VXPgM%+_v44NE??J&O~&v2hquUI;un|oqRaj-;`VUh7q-mCn|}Gyu3Np| zOkecpzmM_FeE(s2|Fmwe_4)Vb566_R;^Ehq%c=8Excyjj8S!pjukz4nhhXX$;zO%* zdDhEwJwL5qKg#p_e0dw^9#I6U87^(i(0M0&YaOC}8n3l&5<^57UfaS9a=3onB1zaYlNsUeW`eSWD%1BEN4)} zI`fdq!ligu3ahedMWCG2;8ajAi(H^~5izo$Rcxf8gfuX~CUQr1ASjImA{u5^xtHJW z*k!)#FE8`;tUvte_Hy$BzFa>X`&q^jcerHj{OY^jdhK^bCUY@KO#yArLM_nDV5LBq zUPegIaE)q~Sr^73c0CWL@bD8@(ToPj0?N`f`_}e1M<+&1lrDtN;fUdx6ey|@`oI3i z|CX?&0sAd*wUnw!HA=|kAOIC&pa!F|&X}9dz}y4$armhYLq(k#KFQ{l4Nax488a*zrP?DKrGhy{z*;MlV5#LiYn)RTo*p$P=(C;2dF+02 znSrS$)zc|8MWy0Q>8-MB<)RDgfCz!!q!pY&uvC^7S!k}oOi5$g3VBILV>;7@kdq;x zQiP1sE)mvx_i?7AP;$z$@i+;W3R)>Lii#8!CqvGuPoi!B_PaXc`lM2GFB%0&X(*r~ z!ew3HLn6yM+F7bRM{Qdga6b^Dek)luX3DA}UPBz%9$bpsYAyW;whqzBMysS7MTk6+ z(rWI!KI^!T?MicaN*pIvWY2Vg)$-wN57Abxn_sTeuBM+}roQA>`Gt?#9=2rz!_QoK z-aJNo_h{qCWz6-l>h@>7-TiQRdeHgjl1`4+5OI2J3m4{T$lEW&%eXtul=j{ z#?UYSkT0vtQ~&kDwJE>+m;PnB^Vj+AeSgf0yvWBt`wPy?ud%G_<8Inkf1PiinU|AK zp_@EBsJfai^0M{OAB`V=?e_lkv&O_siO@=IlJ@919Fg*vP^D@f$s}gH|BZ}WfTa=; zoHywYg~;#@93ZPKSrXy{nUi9g-qLnKovI2-q1<;_6q$q7pc?m6t%mz?t97$V$r&mf zZ&0eXkxlcI%(*^D+&!Bdhg~0JA?_!Qx;!*F8=(=kK3ET?=F>MdcOIvRG6o1Kcq`4q z^s+8FQxv_CQql$YQfQ$-nP*^QKWlVBCN^R)N!f#oHiKYcu3=0KR2q8yDaM2MK@YAJ|uc%&;N%BzV8R8oo% zWzMRiBU;1MJl>==V2E^jCG>~^U^=w4t<|pAZXtz=S@ZPsOeB2dh*?}8`u%OE7*-=> zedsng-1VRQ+y8?q&zPz2RZpyb*o5lp)$Vg z+15PX?s>gW_hTL@n#uhvEtJEwfua&4?7AVGA z@%${~%|~|6vZdTp7;p-wQ=O%OX|jD7T)jW4K14J9>NohsFGF14J(Ps!ah{Q{pWpbv z?zTN{dS1k`_nu#3#(>JQ%*U+`r##-!~_3z?S?e@$1>KASOBtQOfjuva;sp)x} zJ7TPMvE}vm`SYL0@@xF+oAzk^_P6oA% zFwbSScX55_HkVGt8%N-Hn{#D*w)I_m-`e}C%ZJ>L+D}JTWbWxpn?4kcm$gaJ6Cj*P z?4m8_?3IfXg4jP&k-$~$vm4~O2f*h8@o-0mKW{xiJ9fIW{5Jz zVO7=`rECKya&Db54X zHh~O{Gs?g$ZIFf1#e-~#N`Rwkc|a!T$qvgviDHp?PhK$J(4Grur{}VeTF1R)=k0f2e*dTa&wo09xXl~d&@x-jaZgs6)_KrY$rP@2pWFnkZPs~N zIz^?LDuhduI6@Ti*rwMa44!4pcAYj$yH$(y?2B4vxmnkJs4m$?-=wqqsDhMvd;TWf z=i9wHR9Y~FsY%ZyQ~&9||F1z%U7PG-q9D`J2rOm`d3QgFB~C*nCNi=Hqj~O1>2aKM z93EDlGd*A!siJnJXm2g0t*C2Csof*5Qa3@PJxU&uv$~X`l0t)rzzbK-pGu@gmpqGF zW7pvn^}(8ZvBix2KF1sqxQ9pR$Y3zkWb4307TaIL_^xaZblRdWo4;OzD`D%@QsPq1S{|&D4d% zLBYCah3QsQvRaLi-c>RZY|MxwCqzm~J@L%Ado=y<*K&D3*LV7hZ)|b9Uh3UCj!*lj zdAyu&ueUd^+bkcUTdU;z$9&!Ir9$_g=cy_ay@!1HxISO0C+?rx^JC|2?(R)dHuAbW zZ?>8K@Gl}vzx}Iz{0sRs>fQT#fQ&s{{8zuJ?()08jm!J}-8Yx7yT!-&e(|rrULTI- z_*329jk4@*TNfEO#HiY<5Bc=-ly~{~)x*Q+_)bEdSQ_P|?iJ6_@ zCNiLpki%qArnim9TPz!WsP#ftTrxvdMJx{2@?rr^st}%p;8NpFOp+myL|N~)t+F&& zCr+{vP7Fu`!M`XY3RRFqC8&Z#jL7Z&r$7GfKfnL&PvZ+A=#fOSl`tlkb-g^s{S|%H zIogwqkT?s|S0#O>sFaLz)OqT*6(uWjFOO5~vTkj}zN}x#QgzZ*Ayc<2k28|WV)L#K z^ENX>eHNyuVUFPil(AJa&1lI|r4L<9{}=z$f2X7qiXgd2OI@zSF55$D@;1dPhRFG) zxa2u--b=UG_jI54;kUzsd5g0z;!>V4+Vv_M@a`8PpcOmO?yyH)l5~*b9vXAG$QT+5 z9T`!X*-8;?!?7tx23RLdF+HniO}4f6(<}Wr&sfjYnh`lM)3qf|9!gJJjPHMA%f)ZE zzP0QZR7?@Dr90Ba3_^lgteMcY>fRt=x@1gEx}>E+Rj84o$gDF$MZ-Ws)p7tL?V`Dl zkS2(tZoTDz1Ch|xX6l%vgf#d_(Fi9nb0^m&_K6Y^s$gB3pE)7tA>|M$rxJwA_D*XC zut)-eipq-Xx|}zGgi4F#O!VX=$c_3|A`c!;}8iU*p>+ zy*Q3LtRIzm-rru2{q)>-bB^O=jMlB|E%n+OV*hOG+QvPVxm@-9Bs0Pu#{D+;(%Weh z{wcAP%)37QR=(jfj`6A79%|`YugAxCc{Rx?AHUdjS$=bE<7fTD+qitwKiE2du!Hsd zkK)_aF#X3L(%zCwM#R(^Aim^3}D;IbXi`mxrTY{rPcw*w*v!>(6$^ z#ou4ouOBZxW&An6+>iYkU%j`B_RdzjocGu<=hfR|u1)$v98H^y7aVWti?sK8>HYo2 zr!CeeKX1n|SyVp&3uy-;rOA1qG6NN)E!cVu3 zUgn-A!XDZeWu>xmp}+7iddE0GcyBb87S56-G&jUa5w%|9pfoo_L6)^*h)+l($TY2; zYP1rztc`R=M@(c>MT`jq8zUt>>D1mFB{+di>h2KZEK_C!-_SSAKvqf8dRa&@MM{+8 z4RR4#P_K|yIZ>gI5*R&WLe|PmnsSO;N~?0s8HEyP11Yie3J42ibm00GVh`Dbj&gFX z7_yjMr>^gWFQ{kg30^=cg4#uee}M^fP#_8^s6a7a{`B$xJ^uOs>*N3D2uXWOW*@E0 z!=X)C6f&c=)gJ7;k5!k9*_y>1Y|To%W*1YHd3azzHq&9bw7kU>itv2fUwq^#nO)nt zAE3z6MB*H?rigouOewVHVSIk99P7IW1uvw!E`WCDvzkk=pSeD-`>me0d3VE6WwCTWPEta;HZEougQ}c0+ge9R^tH}0 zliLUNx0H>WrlM-m3K>z58Ub77Oh+MM%T&`?D>}&+_Rf;=2)vcdKegigKn#e)>6IJwJR~Pi5~PZ2!Xha^f3(u66Z3 zUis;7b9`67c+U0t(z*H%_3`J!V=ljxcfH4c!5hvu?B#ejwg+9MFS^R)_@c)#$4oxX zdXI~0OGB>m+B&y)9oKK)QsZ_KmFc=}P?@0Zw<+w_kj^4tC(r6_7Hqm=a#{DLdLOZt z&Y&`9(oB4S68S-Par zC&MXKc|xC4m9GW#PDY&`(XJBol6g*Y*!F< zl^XOymw^jr;wNKYah6{qUdu zKVN=6W6Wt?Ylc?L^hTeQLQ3yh-re)EXwH~HN!?m+tBx~R;Xu*>s4&vYvV~(wR30;+ zK?ns^PL!}qRORE}{7c+#!2rqSLiY)H&2FfsS}FJG5~}g=?vWKG*{$n8`49dLNO25Z zpxrPB^UT~MrxC0Zn^yq&7GWag{pN?q(9gY$)t!8G+k_9z4YU&iK zX0QhPV+wWNAPZ+HW)V`35-mYfb=IPmA#y}Mky+B|ZY9~HB8EQ5{p~QJ$38eLBcrZX zz_{-*LeEG{N%z+?OY3w~C*&N9*n$156>|L*40YVcDC-bWLseEp=_))Y+oI=eR|HlO z<~#&F&I!>BCPI~Ht%pbz$$%<{smjBXj2A{`No^~;d5AKa;ao3Pb)R8ytD4O$qP3$$ z!SlLE35%`Oo0Kki9Q@idce83YFkh;*|;n(2OFIm6u+{oNJAbhHHh_auN5) zL%)7rF8#WmOZ=RlestIBoo|0U&$`z-?zeWFF+OUwc78eIvaH^3cQWZwt$UoXB_(4f zo;TmVS~TYCDbMfoeDhrV4SC#Ew1`M)?;n<>^sJYBKaSnb+xg>=hY#%8U%te#+pm6O z_fNjt45_E5b^eH-W_kD(s2e;O~>F+a#Jv~AawpYi1n^S<1d53)V2>uhiye?MP1$JL+SvwM?VW3S^! z#_r?l{E&)TwQXTM6VCgnSRh+_cv`<+mS22>=dXuz|NH`8kjHvP9eZw@&ckQHBiU!3 zJteHAP?}*(DFngn#`GkzrZlY>g8`&zmX#VSVoHmkm?eVfbl0^M-kW5GB;AJ?8YFv2 zEj@}A(i62H6J2x=l^0`_Hk&2gMg_b*EOgifaWcf@W>EeGSiF>lYDuZYhy{$05K|MM z$V6vR1F8!e z1nQ(Np`!UJSs9FVt#gQaAxoR&s0y?T<_wfo6@`vcfi_B0&Y~tRf}zr+5dMg^mu%1l z6_y_BJH%wE>RFT|QdAsC>O3VtZWQkBbprV5aNP`3j7Qq4)BA6%V{`PYG z^k4q@KmV`aP7$E`))`2#W`A+%q*jd?+R(J$U-w?QY#pmD5hPWbE}F>F5_av%ocgpb zvX~b3b3_VtLcy3B6}pIJ7fq>8pL?MoRbisXIO8Yy_O9{NxJ zy?>KMG|%>++)IkGh+bG{R^WWiGc%Bk+}|*&e8yfr@;E;o`?BB9*MqNB6=oXOi`v6# zZK0g9ZPp>}9WbRywF&*E)m`$=b;TUjKGggX4^K=flghBUXIonxN%b^UVBRZMoJR!V z6*tXej+8yP$C`7_+cD%Z#&O;gW;DH87Od7)RV*jKxLkScVbWs)O`SRKF$Z*MKIT#A z5}`DWOsYb}{jSYmO*8Tc2hlRvJKXA2!L_%T`*?Wl`|fPik^Q1ter7VKu5DGm&KSXm z2c7#V+T9L@%7!?mUCwzk0ZX)y=o7SgPtoQHvylzmRUpMS!16QHnBu{8McgG(098P$ zzjBQj#3JKPR(h(mQD{ZjnCpe>cacLX$zs&&k1wD9a30J1ilffAbMQQi$30!o`{(%* zC7YKl3*_^DaveTWR`ES#bymcBUHz$d^HFB{IDKa#pq(1iFLCU`b=lO$7y83oKaAUt zaliTX*XuR2s%DPG!@GqCWR{82-U8?JA zy?q>i_<7VX^8NevewDl%zVQCCzeMV{ZXd8w76tF!Z}2SF>F>gNt{2@l%TLVe?Oaxs z>lJH1k8&^KUh6ZDSC&UDCA#%&{aQY)l3uLB%t98mb&#lJMXFUL&;TC`q|Qv4l3tpg zjp|vUTy|#jG|ZY~LM$X?nfIAhUP{a<#+vh9jZrgQD*fy#bS#||UUEp=RM&0srGg6y zbPZ#aN)}a9q%@pdvJ7-&DhX;vl_Y5;CfuTk%+yXlRV8g>-f2sf&=Zy=&l>mQVq#LB zl~gSsCPvIDO6>w6Ct!%E%qUZc*sdw13h7lt@*?ngd8Cf2R4T&Z4tHGA~Drdnt)a7CIJfBF1j}Bsr{if zslKYLC5?K4Q3YU!CIE`VzhM9Q_NPDp-T&_I{3hC*?8KR3C zP-$DYXre0WC4CWA&a9}KQ1CA@r;s{5$FaZ7DPGkJeFLcv^7{$TT~_M>DQKrww**-vl!UEg6&m?0cu9=BEli%qgKe! z?29Ne5!qT>5Sei>E$B$NfbM~+n0}jM&N#=N>m0KVcR;SDqtGq1_c=zMvX~%M)kZZb zHWM@%H>YT270RTjG?=kQi7AG2$qH&SMq$jnTsS7wM2C5U=o~&nTy)Z8j@%xqx}7J5 z>l|`fa6bhpg4ssBmi7jPA;P0=S0IFfF{PWBiY?`bi_7x<^ixg7%n31PmI}Rig`Pce zY*&lZsdS%x1&RpNs1*7PUFy8|nphS=;kr}^e|6OlWyAa!Se`2n`*F8L z5Q&!`t6lN%;V>@GvHFS6#C&MaS9|wmX}7{Lk7c(H`EXet`?~6aikG*P$9%WiY8#XH zAI494p5Nxz-?VpaYkSX;uP^hXj^$T*eUQ#(L5Q9oYo9aUWq+q#+IpCIqjP-BBVs>V zTWx)Q`1WD@#?Jk6X3Z}zbss5NT)-j*++RhTdX`F!k#rRnRIFIjn$EBWddNbAH*iXC zTT5h<@`9R1z?HOFxe`DKfLWAf$*OD+u{lRmlQX3VM3J>z6_v--a9$o6$~{Dj(#hzm z9Wl+cwF=K=MNw$bG7Z8)yTtHHL6aJx4H2S(-ZX~BnASv;0YRZJI%l!524W_S(x@FZ z3sYibROwdviick!Zm7yya$ybEe4Bhl~6@b0>SX z6>X8q5@s)1E{%Iu?{StD^8~kmXapl@osmQ3FJ@3l$;h^%y!xZnAQ!0t>5Qxj5|AG0 zkmqU>#bC*?>&38)W}?kRS_vUV6_(LJEX*D8g4^5v<>kl!$EW}DKl=VZ`Q7cfE`THs ziqK#Hr8q;aZEMXV>)f04tV5%kT9!$;M0)Q~RHU>5yJ$r=0y$$KgsayClf8+nls5~g zma(1Xn)FD>sH!YhhGuKMppq^PDY|wFWeL<8mV%i2&;G-Iosv|6cD<-9Nq3|odsUb5 zlZ*@qD=?3!4xc{NUtY$kZ+AZp@$)_#7mqHTfpIa^beLdDb#7u)4hrv_jCBH3@s!*r_19HLz$XPA^&dZI;N#C=ejyRNK& zCZ)+-9z2e6(;6&87Uztjh%x|~Wlf1nrLGo3-svy@yO*zid#nHAzq)-t-^!&uryhfi zu4Ikd982>lAabUjXMvQhkJq~_?!`iCZ;Uoy%6fZTWV~v-#&T-A?zt~IC)=p1;W#l)vdwuq8KOw|h^n&cuEGkXMz0cAybuu;z=AsLz7R2KNT#Ej+1yU2c|Fkw_p#a1W!W0_7})V#Gm z1S&21s&UuWi^gRrAi*L5j|>46qIH5~njk0!DsmzVrs+lB0V^rY0cp^c%uI#fh|E-W zvRh1=T`=$IN8wruzTR0rlhVu#XHa-Gxzh(^$?_D6K4QMG8lhss6d(*pbe&%&-$}e> zTdWde5b?TyEjWoo?c1w z8K8tpU+uAp6ve1u@8m`b{(?8miQ_fiUcdbQ$G`oLfA@d*&p-b-U}$Q=)H)p=>ILbI z;U&3snzks}nyPYY8Cp{<1g*|NXT&boi#C({8A35Z)NzJrk_L!Wc~uh;BNQ!V<}Uq` zBPI)=1iY#%cqAKfj&4g+Xp=@wNk1b-jWYdT{rmqaE3=z+6*-yCLIIfpc)jf*2KN|~ zDTxvH`xrjPe7W-$9$(Iv6SoOt_O@;-mj-Da%W5*EK}|&^IR$3TF|2yacu_v;3`nw- zzyYmNnNeDdyRj-$@(iMm-Q~)-=RPCIeGjd9mPg(P=ZQT191<-PkhZK#`-|bZCJc(n z%w#rjsANGPF#}49gg{J-)EO~mEf0pl)DjaVbENcD0U~stiyR8h)>%>THY2x{mE8|F zm+g_9+y}Y#+y(IKyYPcjXxCCnPTjpQWb&?yBF5}pF?$o>Y@5I*g1QJ4C^DxD`UR-c zQ@l|{M4Lu%^P0VHS;CmJ!q_9LpseWYkYE4R<8wRyFaO2w{%^O>-m}T&A?ZviQ2zRg z7I|i$pMCpE??1XqF4w4>DB7h-))?!>{K%uJ`8iMJnDy}fv6uJ^&&DjhD5Bcc_lnp1 zOoggh^5q4OPqJkD>BqHQjc1AI+b3+7lv6%_nV0vqZ4Mu|CB5;(bAJA*j+C!1JbtRz zk8v#XtE+vti9~#sxqgGMzgZq$B&K}-_wllw@4w4OGby#sJn2t48uX;DD_`IvKgaQU zt*=%*nsqL7=j~4sUza@b0gYn(B97Z*-ZBQ*e`c;EWL$ucv5|y7V=a zE;92#PLEuAx8QK@(JJ8X{HG189slrp_v{gpVXs zE<}}}x5+BD%};CGDJJh8buIEj0j(g3BK!r%=eYm;`uo@K|I^?7AOGWz|NL{gS^8nE zDYO|gOU$YQEY(YlVX8@JsiZDzwWU!z{RkCU0WeW%4Yyra=7@1WW~5hyD3dc#>1%JI znj>s8Im2toap&b>Mo`k>O%&QNrwMCmQc^WVm+5iF8E4+cocpf-?0@z@ff%(QpoM12 zsfo}LdE9B5cqkv@8Zk02dAN^0j^lRne$2NMHz<;e;rc{LwJy4C8X?=IwLo@V$Oc~C zMI~3`OmG1uWr!=8A#2tn=TV{z0AA8Ul=G%;vtZ{LRY*6NnLKCYJcoXD-1dFWGqa@4 zs&d&fN0V?aP0GysLurVDOG{)$6NJp_z2`Y)F#^nzKqg7cBpI12l(ls^2N}^&hhsx- z*C?$V>X|d!MaOw5jpt3RbDR)YWzKRXv|v5Y8#usAmdNm0SIJxd`tkZd{#W-;pMLj$ z{=2_@d-r4U1qtOSr*=;U*0T{-1o`Ff;=aW4-k-WWU7EF)f95{pjdT4)`uBqOTJpIE?BS3>7uOSh-%Kd4tE;~C8rDKv`6m85kSDT z$C%0ja+J)66<@JZ)$5! zhhzbyFjG>}R?sDsiwRWbPHLJv-hp1Unl4(TQMwc>V`@;P(289dB3@O{rLw1ip0Gw+ z7*oNrEB)XiD99MKkWzF-vy3YF3-rbi%Yu}6ReCm+_KlhWwW1LefS4a~yy1Sn{_y3e z|LTwb+5hQ}|HYr`%beV<9Ki}{Ek#5v=t4ybajLQPRrf}sIPs?3@tBf_VnoRbiWEP^t!EI_$#eF2+F>*A0x#w}tF z9w`0a{LlY&k*e!2#BU;%dac?)FS%gc(@n-vW5lT7;``0d{fIu_ZlAK={Bm&fPhV)F zm*pziuFKN2uO^pug^QV37`%$6St0aO+bDr#L!RgxZO?Rw);QQxMa!jpz?M?v2&B|` zRyZeXipTD=F<93U)?{iSDRShHCc7JbYzI1i}yI(F}jmvWC$3NvC z_IUoKe3!|H*|h(b7n`*VF9W5(;8?lDl>o98HaGd(>0^rDGq#%neu;22ax#GI%~sgY!v>XhJVBFr$s zEFgE2Hf`{9wE|kDR|6bq6d=;rN=iiFTv=#L+48z-MY~+I4jr(E&en|~64A`=czcNJ&NziKy`tmfI!H?xU)Z@fGnv5OLBn%N!hkM zPbsOmSBMDUJM5tr(L8~LF;Sqd*&%U+JPK}w6$PotGAb}pI*S{vBPRt>6byw>W=m!exFn??1k15p0|cqIf^$-}Qt?R=#Q*`>3NQvixqm6`zsN$u8Kqb1ZJ zh4Ukhi8EjRc>D4H`p^H9|NWo-)8FOGAXJo&fL*jwG^3f&x)Kqt4VWdZHyCnn)*ytZ z%9dka$vN-R7itzNPcQg@!iV3>V`@=FHj^fh;zG&rylfJItaQs9)q5}0IMllET&}%q zt2$&+CeO(IcAP#&Vt5Sve;LC2U)#DYKj<6ZF~*#8t+n?)=iGDeed?*IcDr%FkN_qq zL46b2ik+fDIsw7G|lM_a0q!H`^cu2F}H@K{en`umx zX42~HgGkH?Zc%bvDY-kA;<4Kx5d{t~agw@qDeIMLfq`IB7{QUEAT#A~)_N{XD1Lif zP4e5@KmO(AwdNg{H5OIn;4#Ude&>u#ttmK0OB&`+{JzilIOVd| zJ8CO3G~RUBbaG>>Puv!0RB@uzdCcPuQp*#{1^S?Bt@Pz-F5f-p!^WX@9O*+HLNg_b zF1wq|A^T7p2@Ws{Mo1MTGlqv&CZgcr^oZi_6y#nt!F3XnqkD*)Osq&9P_j(xP!<~i zjd~WDwENgtT?)fJD5y5rq}6*}m3Z;A%8uH&Zl};cB(2j z(P+zfzu$v>;)noP{`~*&A3}ioM3h2;=#eFFSMqlk;mj%Ot~~m@-^U((^4sPmXgN?!Ef`u!o70Gu)A@`+D&r;kt zLBxcrHfa&EfGE#MA+>PLa0`(n(FoVlGTh0L?#mW|lBTB;!V007zMKlk!?To}gF&?{ z>Bb{H9YtM=k{dOG5PO0}n7~mJ5eJq!?-_-ZC_%z8SU6kb4CumwO!q=$ZK2DQ5fDfa zhcTEW5QQMEMqrtC5c6@%*S{QJzxsh?xs1+5Ad!l4m*Kid9mj~{1KY-_=_>|f>XGe35{pg5n7CXu%vaGm2=oiB9G`k)2C z@frsY|Jd6{w5UApiE3YfI`28?V)`NLvNRK(!f7MYb9PXDp!K3#fdY20Kwy;XvevRZ z+T(9y-lmQ0JxO#?9TCLH5tSz>9GV{cv=HW5!>BN4m}g^0CJnOE)TPEj&WBVSvm(VN ziWo;=!MsO86v{PbSMrWR!)Jrv-D~AMcv(fG7*&E2xN7Rw784H6fDZ;|DJ%hb5SY&% zyz=oi^+LR|59jLPngXLFr@Dk4WHVXV!=nTRm2+~UcQlEajKK*df!!lOg5bt5t6Kvy zX8O!9ESGfS*-09q7RqE~Whw<0f|;^WM&w8;RD|by%2{ZH1fsYZsVZ1$2oRi<3OZ%D zc#rLo{hmSvNFvTCM9c?KrLxF;EA_h05{m>&t%ZpfFPA%8UH@-~Z1L6?tX41reLUZUK()B;kHdqS&V& zSGUbyzTMGYZ}xt@_rM-yqybb^8t1lcYmrsmm+uPqQi0YuB8xC@TyKCwG~rAmvZ63q zFlC~rRMAI?dz5GJx8yB@4I9QDf;?_HB4`bjoNmsC<4B3@$Ga!1wc2;r$ss9FM-eAE zF~85cCh8^kn5$}$WY+DXO)~;@)7rEy35#Ibiln1}ENE>wOeO-8K^6;ZCNJ1jNvw+~ zgE%Q9F%Jg^D_6uOr4u(A^YkSB-jOAUSWrR;#w^()*=cf6CTS}X?v% zIY$=ZpxOe?TsTpP{NA&!bPQ(2de-so`ap5GjeP!`ns2Z7pYM!m4lUXROU^qVNg_%! zsjz@E_DG%gtWP<2X|?gyhhg??PaHG$I~9mGBvsDfw#2A4h50BSg6^mfv^&PFJbtLh zF}eq|wAS`L+Nmv!>pov^v3!`apWa`ud6^1YA2SZmcHH~;@sD19#ZPUkx%D67?Mx31 zE1ktK-EZ}Nx~v}`n!L&Fz01bXj-)vk^aZn*J!rT=5h);t>R+u_v?Lz%RO?ABTc{@wOK@@Q!S1Z z_#B?YnaQ+q7`d~^u!zF5Hk&?>tIe^rbV*IJq_RbKp$X0zpkl1sNMP^~VGr)RY9THq zg$3+Z)>V-3A(f#g@s9S8Y{@`o60se@P16_&E=u1VDq1+x+F9m1mB+9s6ye~U6q2+c zZs3#j8zo3;I?=cjF98A(prIrI@PsE(z>cU3Xc51|CjpTzlElGKiO5ur65OEXQ$$?R zBeu}W_8PL0jU;xQH72DycybHbgboKt3(XF$H4lab3h9~cE}Een;pri4L_#%_OAtv= zk`fvVQBYu!=m^Sn$*@vENdODg<#fl^GRFLwUw-$)@BhDl_5c2V{`~*>i~cP=jh2>7 zYi0^VN+wIrsXVf7i7a4-){~NBZ8C31ar0$kAsZGHq6L`DY8FH^Cu~kj5@t_3ogZwB z)|ipXxvmF2Qc@(OZ7R^FgDv7cb z(R7p|T!?qkBzcnTDU}py$;mkhgybYjg7KW}ni%O8sSyM}*gR8+A}oo7Y|rp9%`)!S zahozJ?R|J<)F~(^%xhzqSPD`0Ni0!Gkce0mEJ>7OxKGMF<}qYD<$fcZg%>Ee2PK)Z zsYUgQb-qP;@5p0If~o9Chz^j!MxbdWQ03NmRaww{%omUYy2dMLiX4qs6h>hJpXb&^CQ-L|bb@#22>*=%_}eJ&ff z`1-!@t^9hGcEQho#3*B_IE~YXjr$Azaro(StV?;Qf-mLg*Z#BF_A7cO{qA$2Nnd|A ze<{8GW?X9h^m*B;>@W1~m-*#>@ZYxcb9so?yfrB9@%ClhHhVb9>8zT??s9#nW1sVb zJ${x-m1bq;{%#($#~hDVIJC)1%v3OVyr$Pu1(T_<5~me@VBTF7#1tjL-cGPY zB$okQ(n4@|S@=Foi_ak`j-(|c z)R~Bs1!T-MA&?erArg%}>c;44;&O--sKAodlUYWfc3q!_pO}=b4JXhO154eqcHDIbF!w) zIFb__q>#*3&MUiFB?KXDj@KJO`*4SG27h@=!AhxZO{;RpFN=Q(0p&OMH9w_6Rpy!U(X(g;foZgi!x*jd$`iVurPOm@Ey#vGJX>xq5p?C*ThG!z#q zuw3VC)eEU^Yv!bRo0IB?$GpGA*H?F>s2?`1oS&iz{M*mXx?J>>Qf}Y8J>&}RZ~L3> zRLjGOA#G9cwqAdva&FJ{bTXBDzQNCerzhs)`1$32t@>PQE0QyRJVtD^sXSkl2L14t z@pb9v&#|n!ES2|i{at(^Yrmz3T0YQLa@D);zZ|dUnV;?Qp?&A=L{(M%pzD{tZ`Qt} z6E|&55ARpM?-ReaWi6+o#jAaVj|f;)%X74iS}%;kuM+M@k82EjiuUMj;e`t&m?aO2 z%utI>R8+EEif$L^9EaJ_=lkB7XCye`qwiLj!<{H&W+9F=KRjC<%osDn8~LGa$v*ZV z1-czgvqy*`-wF#vy{@&n1BbCP(QvYvmP9KfsVG4!NXTa?WqCkh$PyJ?E2t86$Rq|U z6Ak1H21nsM2#ZDXcoQuV1HRDlmKtddbR^Y;^XOBHjN3$weNa2+=p2(sXwKls-~%1CAi2csgos&GME zza8JMuRr$x@xS@yzx=P?{@Xv=opl}~QY(s9gmO4VM4OaFG%{OoSxZ_gB?0x$T6DX( zbtRtghqbvTci{d_9@oM=XGH4g-Q9zt5d>VcU{QCMZlpRrXOTWVja`{CC9qvuCURJL zSeDbeU0Nxp0@yLG*Za+e_wwFHffANQ`1@!1H~-$hA%Ff4{v#xj5Y2|TNjPknHL^iR zSn|9be%OAX+wpbO>+bjKaa&1`1oeYXx{@f@WnqeyXsIMM3a_lrvWOgDfDKw>b*N^^ zjEm%J(89$sJIg83#jgQED5M)S%?nL7=0t=$!Fr@F-lsWRV#PGy)-vbsfOk5=T?0qtc|>JiF? zX{qAD1YRYna5#p!h`4oBU90y)ppy;;32CIUnp+Y=h_bAlBXg9ca4<(;X=MzPQh8=k zfpZkWa3V-kA0UsiFelB>xRabId=d(jP8;8QYAGL|>0kNN@yFl2z0-ZiP?n{_?+}!x zWVz-0Jj`cd4cv_-N9ESeeX`7#;74;?$!bz4JDp5o5@o5lf5ZK*<_7ONoB!%# zd!$mF$CXE$FE)tsVJQz+J+&HG`d?C>r(FUk+0fRZ%yRrP-tS|67u(hrE)|;Z(GR;j z@zboQP$}Xp>Yct~q*+<#Vj1Zp55T4++m>=6oeIl2eF@5&@L6P*%O``9nPao$>Qu z9X+COhEFc;8A&r(icB|xdS-yEY)3{ZYZ_pA4Fgrj^zyj)?SSe&lXG`&T$EdQo9S!r zlSD^vpu2sFUznTe9*#6o3>N)(|2ld5ik z6z0qfWJa=C#4Y%ok%8%Q<4IK02p4h)Bo`1>(lcB+8|U?Wjs*ghEm?N0=ce^n|LC zgK3(m=91+O6OFGd9|A6Pk9aJ3PdAD+kW7WdoGY+fZrnK2#Up*t+5)VxPp!a4J}E~M zRDl^p20_?Hwo@l=nYt*HDB+#bnX1qZs=klf0AWsIg_hHG@2@}H|LUK9`)~i{{y+SD zOkVvkYPtxx=y7{bPX@TC+t5~OUBrVp=iS#7*0803f$##9LgcJIiPXoi={aIg>TWY4 zNd{1bL%CHVq0&JHkLei}LC+sJ$kWK97Bny*AmRl=RJAnJecqF6-;bBKw`2F|e)k}* z+W1#b?ce#ge*3TfE5DUL|3Ch(AwqUbX*3bTBg@1FP~NXJsgvft??!$<-fq_S`)7WQ}Z2hh$@iDnE>R&r-nCW17O z5C$f9sXVT3E*X^RJHdxhn<+QPxb7b4H_2pq6p#=|lu|OJD3^$tRALU?8fL*s!IdU4JG^G3K62cHv`~1ckVO+B$}Diw5>|Pn>X@OzB|K^> zr58)C~TeUMcG1mXWi+`)jw4ANl+9cK^xm>xdhC3PpMRxbn;C{mt~F)R5wMzs~co z{o!L=U;3Bh3x8jqYNZ{1s-G4aKhGEV)b&Fn-}@i=Rkr$k5uy41`u0WnSI^6b(>V_N z;ica(Kc8j$ROm*ynzt69aQX|XVa6dU(vo> zC@UR&-04MpR6A{`2U;)}KJMswyw*5_YC&QCJki^E@D40EjF(_-VzIqKv|c^?eg76pLFYoHsRB$YBRWv3G-PQ z6R13GS85zn$IaS>=262)xQc;l@gtc{RC7!&%qk#>-7>v*Nw(#K+z(6c$_Pquj%jVt z9*dYt#KASJY*ms;3EQJ6DNSheg(aL*#P2B^ZB4W4d|_I|k5I%E*kB?^xCqr|9y~pr zGK$0)sd3!Hx@Yl>n8z#++>g{vzzELPG$uu&o*|TR5H0C9%}7#6r7-v&QN5U=prs5G zAux!Ngp!DB`pB3C7|flRGgWMN14tI^Z8%< zvyXrK^GW{v@Bh2xo!~h<#z9j2K<1mfa~{m#T7k;Mi$f!-JQ`1hT=}+z->DNd)1g(d-nSRV9Ok0uJ|-f;gy` zD4Nqun~?i{43B-EaqClM-pxUWBiyTGKt!TtMoJW2K0L?Wv@DWIqNPdH2j*lENMj$; zDg)%Ak(5cyC5CGWkgy9DcY~n_dqy?}(r2*GOh73qnUh4=V@kn(r&VNhLXd)qI7QrK z1mz%>3=&FSmrl?$t}Ce2aUDctDdI;KA;vzuEFg)s$fRjgcqvMX@J#Vpb0#ITW(!qZ zzJGrHdz`=f-RnPnH{nW@$-+dOWR|Q^*mBV_<31w9)@3P3axG;oOvn-lk3^9;qML5w zW9WXnz9l|AwNtHMf3mKFI}c>J*m>on?{9;aM>!XH`LW-@r&7<@_MeZP=68RxerWRY zgRYn5L-Fg#A-3@PD69W`eOYa#^K+?fA3q(VGk^YY`mnWr>tFY~*5!k?mU#bbd)4vb z+#b9>tn~6_{CqV$=dU)}%H#7=;|uN{$8X00JTrt0o;K zhwtxneV^~|(~bk3YBRo z#MCYvRJTfwq8X`El*$_2-H&53J8JRdLS!-zBAFg1@kvGfoQh@XPDiIXNQCbC}Q3s(NxRA#IC3 z@;F$900s)P(nv&yW{=x3C5bW>f)ZnzmS)4lMv#z53Pq5TN)shz>NO=IDz!;~$8nE2 z2KfP3MuhJSDGHvnJTxv+>WMN~%W=QWqYv;glY%X+uzuX?zy4>R{_bxtf9I1vKCklU z|KJ}GEirfU>Q2yf8|*W~az6r;FYja6d*|crc!{t zLn(!YO}CBv6dF*M(hx0iV}|ns`>S~25@DPXT#;6DQpQB7v>%zEG%_SJ*?nS_F?>=? z8?r?A(ffX|Prn`!t-^wnxM&erkWdhjzD7D60vJ+danFy`u`7YYhD zX*rD(K?2US>B=IWsw_3#lt@}(A9&cx{g|^$DLIYTI?YIeM=!FaWORoz*OV-|)|`8^ zbI}k;Bvc^lGTc*2#vamoKd99VVu~=MZIOPoF-JogJ*9A1b`zqg=K)G4amL-Tw#N@2 z%kfuV{;O}lysr%t8dM`o&3!+5hM80GeRzzb)khA-` zepuz_kC%2UZ~aOwq*1U+#KU&77yy0vARCPzzFhrDPuybaeb0_^S&p^Pr?R&8%U@lOg`2Do<@~vo+mEx~4lQl1XSw>%_jxb+aoJAKdiz8C zyw9QY&%W2sTdPv{pYru(&XX-Gov*Tj$|KVa-LUh$JoDod*P{aBSNisoclPC@iO8}n za&NfG@l(GR)6a-vo2;wDCpqQqWzuGOj`fkH*PKk2c8vWVu}#^sv}mjFZnqbIfAz2L zcRzLgbeB(Y`3-LiU(UKRw`Eb0rLNBpPrq6pfBW?K{loL0JeEKG#OFtU|Ap?hUq=lq z!aQsOo}Q{XfEXo5fcwqbr3D1i=WxS6i4YmMsVp}3^7L3Nk9|-91%as4 zhE`f(E}@eP#Jr27&sZv9tvCpc>-0coD4}L%#K3x~HtMNmWfPTR+v9h0zaQ!0ILP3j zAhZSyjzWmS1#scoO3Q_4+VwhKj@$jPF?fI`$5tQD5BOJp{q(2*lfU)1KDX!dhwUll zAN~D*EAx&R1C7Gi5BD0~X-w~F*W2#vpz-oXufELdeb&Ig`S02D@NAN}| zLbut;ZFqPe(Vb^lPI5?0(~3yeAe5%wqqG8dE+`=8$SFy5bbkD3a}tuJ6kgLNlEO2T zEC~!KlXaA)ITNBBG{F&s^qA+ej$vK`!I(prhgf+!2NP<77mCPM717*;tw{zg$%kh^ z$t=5}#o=MhwWQB^M=lLTC}{!XRD>gCA<9~WlBZ=5nf6jqjO(JJ-J{K95fWcNKP-Ri z^!1si`-ncrqnwa*W_-~H8-n>?O$?sGOPb&hv?7kB1W zV}IMb&`D^T*Tt*lMAe`~9zwk0<(c zd3-8c-thI?n7^LOV>zXihvHYk%v(~|1j#1LCAC0~AL4$q>o)Z}-c+Lo= zY?o&}o%z({R83V*jX+wfZI#cpoR>Ja_OS88qpXkTY-|7hAIAHgB$F@$OJ!hqSr<$O ziTPCZ3ML%gH2}t#Nt0+Rw4@fI90^O&3wB;eu!chd+p3L(l8tu*H4@}P47%se$1 zIiSoW67S%rsU=d^T9?e-Yh$71{{G$r3O;hSr3GbCTaww+I7N#fgsH5u zK2(-#skamJ4Ko{G_YA?t2cD&ps83n0*`9sx3R9J-BnY3||`%-y3pM++U6PG|~!ljnTOmHvR z2mxIn3)r)5 zg_aQE+?~!%&nNO^-%Fm84;D!+^mxH`(d#alA{stOVW&mrr1L_fXQ(oQ9Ocntu>TE_ zwPZrllykbuwnj|J&D}|JWe;6fHzp}85<`|nvN;iihFdxz+$m$uLXBHB3|=p`4*?eL zkdxEyq)eLoBm_zc1my%GXkp1fh$i0;N>X=BFGK-iJsy8kr0ie+#r}3wf|YHJz30U4 zA^>xY2tNv~73>5gh|9(WW%!|-Ze*F!_wuyH4Sv17+Ue6HE_(j)%W>QB{Hgbud*AD? z3VDvskKaj^dA;6mLZ?$(iC;CfD*2t)#Iqb2Z`|KbNTj%m?a;cnp)}CxHa3B{PbKeWmT5z596o7@j~|z%l#BEQT;ZakM8bh& zrb!XZ11y}*LK4!{Tg`TUI*#M^yB{;vQz&uR0n1%2Z-_CI|Cc*)lzIVY|}$ z5Gi2x%#?-ljk8je2!jfZiCDsK5CWJ|fSyE=XXtH4k)lDHAZTXh0ogJlNhqE29#SRJ z6Oajh%z2ea(ndUhL?&|wM5Hi)1d4KkiHWNxOHrK$B_Z;Czuo4ypKkxZANzm*$N3U@ zG`4+0P>L!!N`cq#owO3;^z>oB4o*@KWkRC+1XPQAKw?A?GGNmzD(Yc#WTGyH1m{dY zF=zUDVK_S|*@DQqLi8F3+8pHc=nsMLX2UxVUR!{5t zd}@E|x0jE<{rD%BJfE7b5HG214yrz>*L3CT{WHhNebQOEUehCX9>cnWKnWwufl6QgFv97#20lnP!> zs8;R)a`eMJxGXt(Xk{DJSWw7k4&o(JN;~!p5d>P52>1jgi325VRL?ARk@y>AS!#nb zRVm|6kI%f{Tv)a?PaoU+8-)e8s!Un9nC=Hom$~=kLVf6V7P!m_AlfOB;i#2D3j9!` z9=d4k)4F4wGBe1E9M@!WaFcUI6g>{KhVw)5 z?pxKoWj3Xx^jbj2{dz2?PmiroUfs%SiwA$;`&-g9Q9f-rYk|hsKOW2X>o%70-e2~^ zq@1NrZxmQB$&&Nyym5Pcs`Q4}(eLRWzN;IR*T0UJuA4l@3w`7LdR$N84_G(ZUK_ivC*i~~kFQ^b{6;>v_8>BbdXN35akrqeZ6{tN#y1&l ze*0tpR!99V&L8CYV_8lQ7jI?Rw2QLH!fE&$oGHnPbkAgjX9}eUZB8OdaxMZycv2b%F>A-vx^p{Q~= z6QR_h)3Ppw3hlMQ6*@bXMluwVl#G(KV(tVnkoXlMOiJ@E=|~TR3DTat(mLP{*0ZyW{U?2}Og4bzww zPf`jZA7BN&au!mcBtawkeaDwC`@i@XZ~y&I^JkRaBO`^OPLpO@S{fs>4+O9Z!X66Mp zJP!t=Xh|$%Iku%6s)aE z;Uy?Q%R&^a;1&pG@6?3-?!?imP7imEL6j*>lYs!z=#snxHEksyG#yF99h2sLkE9rL z!f(5H4zDr-8F?JR%;e6c9-+&CR~{}KN#Xm~xjwVMQ^3Qb8z{*F-chti^45ea??)*)%S9Th zXrZVrksFO<8bM6;#Eq&=SB-JA$CEh(I{OTn2(TM7q!n0A7#HKqXFKNg+5rw9IfC{~ zF5D03mZ%{HQC);=kYN$9l8iE_msZAYcLQZ<^@tuV>0CfBulv>P({};O+x711%ZDnI_m{2@e9~oH_iwh#rJlDF58HR=T7G+4wv@mA zyFXQdAZ)<+8v0Yko#KhaXeT(DH^g#uux`o6Zx3~C8BR=5y0julcN{wgdu}82S z?AzyZzSRgCSDH4juiiPA&mmclce(y?9v|;_o7>0y{Ok4ke0iwr8nsBJ5XtZ?Y}CYQ z35OG5?up{8o=74>2MNJlHi}>kFjS^4wfpP!U;MNWn|-9PCXoaSfF|=!TB}*Grj0C% zNGM8DMAlGZE(ypn4YG2$_b3vx=k`FvrA9_XM5lfYOPPBVCL~1> zl%Vr>o+Aks2!>QCG=*#7GQERy4g}Xdjfmiw6vaHlSy2dHgao=sDN8F@9v_aG)@QdF zGu&LNF3a-k=l0#7eEgH&oPYJ}$IqvF=3P}~2_=$$_@DgS8D`}v_B(k5sRfVgn@79u zV@}@#Z}0Qgj|f|s6KYHn1$`FEBxQs*lx1DmxbQ`*P%;tMrc0ynB49e8Ez?+%T&NO( z#T?kf&xsPXrW7R@p5QCH5>D&|8-xO%0+(vPE1 z^5|45O;2YKgs#>6VYnpPp-S)wg^bbboSth>t_pdXh!`OZ@VK|Kg+l z##iFANP8%2jhC1HOP~7dI4`-Dbum@V+39v1cQ#62A83`@?uAMod%oZMs9rAAr1;hE z_pwv2AL!|`JUrB=_2KcfsxQshO&ezv3MTSQVvc|&6n+g<#z-(zvMNQAlVCC&qB18D z5Tjv_ezNyp`j4+~M{dfc7Gq?%mla`%G%m~$B($Eg!PNnhQ(+*~qa>9NUiqe#8i&{8CbmjRD1X-{uS)@dcAS7sK ztQiARAx=^_m7S6^vnFTy37zF~5B~zWsFj@BiiTKYZ)&feFIOBI38M;_dO_`1Y0R zR#Isn4^Pk6_qUR19F27rE~k}E!tMZrz=f&1HUJc&y}Nsu1tt8*0xgy5D$Bzs?)TEd zN}<7>B0OUl)uNnC=EF0kXrnM~r&{>b>SX@ziBO{6+#+wg<}AU zn5YZq^>tXL%NPeTu%2{WEei_s-g&*$ab#O51d9~P2-l*yGf^N0GpE^oJer~2`M+iY*w z{q=fS``ngz(p~o3{`$Ur{H`=#=CqgLZ})Qk5XE4Fet2!`YRpwOzki!Q z7W(aX?a$i6CS}gwo3&G%G9R<7pLKi4_h04@y&sqP;Z(NQR+}`EU4{Oa<+QLV2 zQ*t-JzL{?9BSbg`Y)@fkC1=h%yC;~zAae+UGCL6`FHV%85Va7Ka&OP`+b{1gci#;q z0g6b*LXU|1TZGfK z_rWsVm*DAXPOCC!GVPEj*lHNfaS~Qu*9%a=uk`~#aCyAbj40p;T zML6*pahRSm6*RI{ndEGclq6>@F@scMcWUB2<&x;a&5^+m97A>S6wMiRlesfyuFqVR z!-+ZWNAK~|&-Z`+)A;XxJl@`HGC2l#&Fh`R*(vY$*0!9T*?HN3 ziK}qcRweFOHtu^TE*aMM!-l!vo9gM(e)Ij)uYUFL{PFbM`nf?gxsWO_6YBEk|LMQa z8RNJO)|f_fj7-1BF^(SkcAvYXxy+yf33n9HODS`tk=+lj6-0zR$p#L$>Gvan2fJ-SLP0B(TOspgbWJ=bW_j?4StwP2#(f3UDtyYGI zVjif)59i7{o!T1g#oa;|%xMCiT(}gdQi+k5kN$p~R+1#I6_F7mG6YdA-G`FQpmIv2 zNt)Njvz5jatT|XX>VlA(ho>lef(txWQKfW%K<2V8DNGs5iH~s~BW8#7xFsTTx)o1s zg|s^5B(Ush!i|b7#x2t8vg}9T+{i}h_t&|eK7BanmF7@#7LB)8rnR0H^eZ1~O?bbF z<#Bn^7Uli*{i_{2Y~F@%T31N7=S=)@tLp zq7TT2?`WNTjJbzH=3`NCzP%o{@v`D^VPZCos7^Yw@E z;!clUIrne=vO9gG55M70&-%F4^|CZQmmPX$>EKEkX+kk$l3)gJOhzacA~AuP9Pq`% zCHKflyeN4jkQMC2#Jm8>5n$pba#=@xwBP^ocJJ^MPvR6~w~$InL^gzqle6cVJi?uY ziDybOI*`+enF%(iQQiXH2U1AU#I;ptQpQ%L%^S-Kq7>Ja5|xx??o>{YJ%vC*?&MAh z&P??*m*fbmjWaSW90pYHz_^<%us+5z!)}rL9J5!rPu+GiHL{#q8!c5L$5u7AEDj5= zXSd0oynVv{no>xTXo);Dlj<2TK#7@2(}t60Ibk}AM-ss7J52e zJu&xq_{8&0LvewgDG>m6iwSXHF(PMon#mH{R1Os)@#X%Pp6r-jcz;usxCpzuf85B_I458{X!IF88G?q82y`i!qvIvjSl`y4ch z*Mc-@nuk*YB~%MnElISX)aAUOB6SnB9>}Uyng}wvBon1myO7S{L_DS5L6oFWfprQA z5vntN5!;Qc#0|p{h|)2cI)_A#VL76sPr7}WCgN}8nsXw<*g!A>NhwNUr7975@Y2{O zWh9u3hLp~hW(}bIphoE#?TOQbjJ;4RtP8i5rbnUZOcD^m(Gkv4!!pvPcO%&(EtQ}? zjl^q2Z5Uj1nz2?;1oOkA5o+huRF1KH;QO7l2|Aor$(6}GOUvu763NL#sA^H!CpQ=o z&jg!H%WW%>dZ91W)h4mt59fS=HH;6 z#BNLgF$Y(n8G%ef5^*HNL!+A@!taR?R_84U934_K8!{+HZL%$-+j(@q|NgIoW)<~5 zLv^M}&%sICHx3NFrA$a~_pdJuYoSn`>XKyuY0 zf{EZJvU6#<)yRd%?$QvGp~)pF(pV@%M8Ff0(Hjopd8I7o;E?gMQl$MdW?J);R;e5~f9i=&eN`X}125F8ET0xAsYiS@4 zy7yl9AO85eug5?A1^@DwZ=Ga}1SZ{&nZ(i4pjEk0X(u^9(llWzrBG8*i6G6903}ED z`QCF3Ue-9^!Aw1h1Q+8-kZ|Qw)oFzhDK#*im}Dn4Mgj$mB^87aW-o2!BvB%1Ri#yw zR*1E5PK!R~B#s>Cr9M1upU&m+`;VV4^7*l8Lwh)-dGKrj9~MO-tNg?N_n)16#% z_?UCt{TT7}Ci_0FyYCZ;q=mOsE{!5Il9x(HNNE{EeQ;565%f}8jU;7$tSTusSruA^ z1GOMmXfP9;m?o9Vz9%<0B?JVT$pB&JT!DlAa3Waq7?By7LDhO6mP5pDwkMlN21C^| z(6|(#QY$&dEQSOv3=4CiYz>}zOcqjxL?n}>p;W&I=SDcuh*2=Mq9EHx*HXwkm17<& zEvTEkU%7HoBA2fQ`tV_GH?2e-a}n%sULKZ<7CMp&txUFiX}vQpr7mi(xBXVj_m^en zSqO!q)rPd|8!itGvt8dfpRD)t+fVEDOWv-BZN6d6S(g}pcsa0cpU;hZzW3X;V&(1m zx!67LeP$`=+UiP5{(5tM$WQC?Ty=5#av$|vKT)M2RozCu+~&IGM=DP%%PRKE{C3c{ zt1Zv8gq+Vpq;=zTdi!Je*2|}|g<$aB<^EHAyV^@Rav3QRsnh29@9O8r_4%}2WILZ* zYb(Byu9|P8H9R=GC#6v$au9K#)S!lWhor|UaZhQ8>7+`@Rc4&XgFwinRMnAOeX8;f zECyh8s~*5D`N)(5VwD11ix27Fn<;W`*5S znajp@2$`VCQpg$=m(o-^^CYQba({n+{j&elAI4w&{^j+^X~=$%I8Gb*IhY!CxJv?p?PnT7rZtLPV zb1*R?oKH3nSx@p0|NZ|td1hJ+@_G2}-rvT3A2(1eui*S76*r+C~Y6(c#|Q*#Elb7$=~jJ zkRE-cFcI~6a9ONmy&k@tEvPkwM0xmawKr@_95i$Ipr8oj`sw+US3V92O|!fmylhca z-rur38XasS4W6p!R`0KNi+iwqs*5bzZ*vn~%E^x1H>qVQbKa+=_VZGGKL1*52 z6=Zv+pTFS7@$s>ym&eDl)cE!~|6qO-e-_!G8AaaW`i9)c%lmAfcni^kb@lu0_`@IO z&w8})CM0)bU-Rj6{rItc_pqL{wzgDXFDtR24^;B8YW{?nZYTH)$wEm9W2#V99D&Ae zgu8RYv~1%msdgmZZgzGH=A2k;v%eg%GpHbsy4Q@v zGD8@k^-SO#14TJ&fC7cHO0ks95E7h%1anLY%d*J*DkLzbc|$HFL!}F!i6tDz@%rr* zzx(}{fASam%k?_A+UP_|l!Vkk#7^AG%mZ`LWxACDnUyo-07;dl<$gase470&v=L9$ z<{0T^r226TCm#;>vS?8#APfy+Q4d`2yHV8$Yes)(X4u97&WTMf@ma%8-BbzxsPX zc)AVDe(b}qhTF)m@1sv9PDWZi)#4LaB@s+Hb6Le_rVx3S3aMq?^lVF2SuTnUBC*Lu zMJgzB*(yuQqzp_@ae`)Cvn$ln2sSX1ln5KgK`3%K5mMH?kE9YI=*NtJ;o#y^De{PY zhKv#BQOvzDGyn<8Qq>ZfER?(yICBFLAT)Vp%rHn5QzS8~gNQ~4K<92u`Jmj&1HP^xsqm%$g%~K@8 zV@_xFyJ0OLoW8yxHXJ-#4|iJMGH`ihkDNSPOLE%h?Pj)|+Un)yesrR>YHN!p-DlMk z^WAr&vf@-)@qF9IewSbU>7`ng7%x6)tB=AlkktoK8Oc_dn2WpWM8Z{FEr0lor=l|GImA zuzaMAv@XR51@d?~evW<%%fxtRTI}(&{Q7zMa9);p+EfczLYRddNi#(J-O>CmdHfO@ z8JEmENnuZjQF`VC*ExlKmb|AvrjGz599)19<|r*^3LFx|jdMDIZGaDe0yT^@JB#O8 zef?Gb@`wFvCmU5{WSWTBV96js29#}ijGV~@vIvbq)%)Gjs*1xV=}gk>QL1ZMJV7K? z3baVDWC1Z!bYVK6fSE|ajHCz+_~4#|;83EQ@q%CwNRwzYBDMoA6d-?3URfGko-pF`xGlNLJFZLT8d!agSSj4 zmJDXjbVMe+2QEB~Dv>CxQzj71HQ8tyLnYsn7VS4o&781%QZ1Q*Mf@GIFqkwls-HHd z$waCF%6{Fy9{Sfm^}qV7pZ|K`Mk0&MnanAm#-MOUO16*`2r-v!We+?Ex55j$cMh|O zlKj65<+TF2y6kM6@JGLUIe z$fu3{u-He9k)b>Xg;Kuv7U5BdvfYE!8=ts_kK`I2B%;~9MZp+Z6Q-$BETU=@WH~Df z5t6}k#? zV%>wZR?NEqhDOJ`5lbm_f6pxPSRPAi-z7Qdh~s|Lv(Dc73+Y)e=aye+?`%BUQme<+ z!ko6cc^Hc;}q+>+1oL9mMuV+)kfU+ z<64&Q&r4J6DRlzyxIDjyqIpGRq6OTUhnhUAIJPWV&<)nd6Mt`tp4f8%bC|p*-l(| z<8Y~h1VwV(i76<}lwz2)nJXK-c=AOh2*|la?1(~07II%GcMwbq6K8+}96JQeJ@gbV zxW6;q11n){dsEkPXv!}(RiZZVAZ(alNMMI4dT6l9}7bX(YL&J+cfn$wtx z>3}@)xMgdEHED>~j6o_&Be`-6LKVB&x_~v(!J6rW(Cl#cQf1x~D=3&bb0#bqS(e5PC`@Cy? zh}fBHT?>a2Mr~RfOQ>XVa|72!z^PmlCdv*ObD9)OKkU$2yn9)T$~^0$l1qghJ|_)} znWjd^5kaKP$^;*AIxSDn&cfrE!_}dvQ~IeqNUb^Pf|`9?o=%VF<>|xY)2HWi84njN z?ZR4_TnL$-!#pBD(wCSomL&g|fA8NV=d`^W4X2lE_ua>Rn903cTO^wz!9-eUb`xPX zGeVg&Ws@~|(p=><4_#_wU8P7#**1b|fdr*nuBY@nq%wevl$v&9Q4)n+cw9+OlmbXb zCJjo^BtmA6u*@*2)kfGcCLWIKdw4aAs|W2iqeogyk(AWnW@{}(#BeCXJc773FT9Zf z%$d$6OUs$$0ZmyRs9$*xh+y9GwA9^6iZ2?YOCG5g8@;hbx8Nc%SSzw~DJ!x&qlAtz zQgf-;SO@vqqzNDQ8baWdT5u;>U|z+QYaP*3MUb4F>}3g#QjuIF;~u0IV4<9h%*%85 zAwKS%Z--q&r8TCR?-5mwJ`8E&YS#q)kOgXfIxwSFpy~=(+{9YGNVXMHKWNi;zYlcW-m8ULMw$wJ_zn_Sg5Ze!FccHA$E8 z)dEY=kH(a+n5y64T%so8>wW*_o|lbE=&kv1|048q;$JnQ``7vV@cNBCo@lWmpNbIO zzs#>;xa3mga%g=PuKuV0)PL#6S2{*R|Ke|H&+GP2f4h9QZbeJo8V*{TmgYnp9h5#T zr^(#IXK+KR{6Ig0#>lSngo6A6X~APIIPRifdwsX^(UsN|B%$4B_B* zif~F|B>gHqSPG0Q6Wwz1e%;?b_P_hP_y6tZ>lZ6_`4;vL_w}^+bhF;=zVHHZWUG~6 z&L?hL)1vGd_hVp6X`|ok+NK#2oD_XzkcGv_;OfHEQ`ygpoYq=7Cj}YYESW)qfU&Hn zlTxEaoML_X0k)@kv60r8L5ZlwQ?h}GcwTGdQe{1t%X4{H`LWP)DNC`cA$%gdayiGG z2Qs7j7~wsNx>osr|J#2?)<>ir{kZzu*W;s`A$uf?mPklYBoz^N4Ni?vq-YXARKSiD z4%Bi{FIaQ!#e?-C+C!xjQJYMv_CfWDkinK@47cvd-7+%wo|5F|Q%EI5PpmP|iv(4r3`SKVMlh$lFwY#Q%8JuD^59Y| zk?;|~rIuXMcS@Nhalckxf|32|rv;8oVIH-RkQfsKnlXcU8j^G=NTc)u$5MPB%r&)7 zdc?jLHP_-EOU3k%WkWd&j|4$7j5v_j1GQ#2aU<(7Lkc(QMvKZgruT_)8@`<6xY|8q zi3Xk|AtGEX%!6fF#{{RZuxS`hetBL`ePLFJ^O(mpU4kc@&spev-X3R+k`sr z?{jbQv|Y-v%AD4uy09DSqRn1Huifr(FaM`&0tb}_06yovob^qxYk<+aY3Hhyj_ucss=f`g@r^b~< zd+=8BGnW$>))Vn1p(Avd&~(A!R3M9%o6Dp1Q2WYd$t)lTgmOul@DwB$A9;~sD)-Pu zC_R08p*WDF43~$HRWwOjf=CsmX$Dw`*r{O5riU&oZtePqKkU0<>@EvYA!ftWqM@yr zcbnzNE|VS}T$>ANVXBAFvWF+4LP2uU#KmFG;(Oa>xgd;}Fn)))pQX3E;aQgWcz zRB%jWFlun2S{y1_{Iu}!Y&B@rr6iEViM;Oj`_JR=|7d^nr}w{q)BE6lyz+0qU(V0+ z+spF!BDL`QV6hp>835_3t(F+kYR=Apg9_!)S~!ABoA;TO5-d`ubHHLLJdGqMu`UHR z5hS90A6DD!5;bFXN^wup>9f-@rA|3rcsN)yjUlbH+P2!1y_B?Cno686+xgTUFPF>9 zxmJH%r4;5==7U36Tr7^`$bor3W)nGoYAebA^1uIYgZOY9`xry6Ge+>eXDT5gF?oHG z+_h{rP1s$Sql67{X2xL6IV3~Y3g9f05>=~8=Mo%A2rLECrCw5ma!+n>%hP`rr2nP(ckF?adk9}Hzr3#U9I8)J)QnXJgKf4xWTMKTJ@2Ai<*C_ra;#Gvfwh-&P@Ts~S_Q z`0e<3k7E$mN$otnD;X15sIXV5Sv^8QAYvudl5RP6l*@8fSJtI0<9L_h8BNZM9=r3> zE{l(kv(u#NC!vYs{p+4j`ck%jtx>3gPYcb1owz*H;(Yzur+%HQZr%z?jt@V}T9#GN zU&}r|@{*snR`X;#-R^#0M53~xkJu^YL`yGxURTeX2bgQJk(ZM8HKyoOD>{_yxLc`< z=GQ8loF4M}^_VC9VJ$rB@~v!}_8*UT%A?>DF~o*~9c`IE{doK``u*K*)9VlAFMhZF z`P2HM>uD=xiX18el!%N$Dp$`k$DBtApCJWBoKA+bh(npXFY>1;FXqdVUq~l#qM}Yy zJP8@x*l)z?E@Ys%nQW0YX}Vq{6Qz|ZQYyy~RdcF(K+mkg8md(Y7Mv7H$2dPvTKk`V z-me|U&Q-!p(L0fi$;@W#g=JcgDHiE&H-o|>Gcsn$qYIMP(<~)exadhq#I-0BX&$yc zm)J=fONyLQCS?U?=$RoPPykXW2a=r|63UUh&1K^(@Xk`B6%2>S;XvPysmGk-u-ld1 zj^TkpkX5l;E5w^JNv%=}vqtgcWUa{_#Em$~Gf7B`_yDaa%C@5}2nRz%!@)7R1Y0sP zg-H~Y?3x1h9taFe2Ct85cMe3=oV`edI3;OLrxTURY;E4aOs5CTn;m)mxPSh``@jGD z>)(8pw`o`lE&A!7{jfYg-T(Mm=RtGo>A`K12UEx*!XyI+51CA6GbIr@BDtzh&#Wtx zl`(CEg%7Wq(=oiHTUv;X*NDx-q+kPm*XPQCX)_%tQd;A?!PN(PMhvlS`JEBbhi52;s~wYYs0<4L3e4 z7lchIm2D6?GeHNZlyu{hkf&Kv5$)7nYK<|qHev6+N<@O1?XE4=>dd5s69dEs*`)7S z*5C*sC#5-@pc*g}rktS_7UQ<_ZBA2&6r{;*cPg=Jv6{+Cx-1;CuUrW(BHV45*T>RW z-AQTAzK`Tx9*Hxe8=o(FN1tQ&ad|8;$Cq(j@4cMc<#8QfGS2Z(OPSTD+mZ{)X^r>m zvA6rDPxWzI2r}ouQXbDmZd*6Iv)fv~TU)8DNB__rZJaKT=K~$L&Y88oXql;{+1rTq zRMs2FqSWKvsT;`3JZQ&!KjeH$Nip!adlWAr&!`V7mv2DV{CMr}5A^gP=N()z!^eoP zyI=Ql#r5d7`=k8Re}4IAzkU1`+oH9Bv|=V16MZBxk`XIzUlKj|V#vfWL+S_QVm%p+=w19*LNSmCvs;7xI_`Lp6!9>VD2$beE-U=_{flI ziEb2gbScMSG4nW%56anxDNhtlcG6fEQPQ?zJCh9~=1Ss3Z6h93HwG~rq>7Qef)$zR zVN%hJFBduv6wVN!q~ED-oKt}CDe1wS!lvMYd8d8?C4Iw3OwNr@9slp^5c5@gYpm%FMd0`(^FJPyP#2J1IALNB>a74x+rj$f7TfjZpW7ddF zo8yW@FsB_JHghs&xF_v1N)xmVl@&@wQHiNkwhEyfOf(l=MS?>ncQZO8Ckc~tL`d;a z+oh%uU}V>wRg@`&B%_3)R!%D{Q8t+~(%k~8nOQ~r^a)5Ph}4l~y`*`{ECi(Ww$z!B zAk-|P;d^+Ig8L4xQ`@AWnKDHR5bR#CFxw(qWgpl3*t>8EnMG|U3MyO+i7PD*QGsB)6_a27ZQ)@P9f z?!dPBMx~zV`ub+NK9v*2d0unqST5_imIZ=5?iS~hoTHIr|DgLar7oBGz$Te9+AJ(D zrxs4ZzQ4w4VZHj-JqL|_bsE%4N}=5kY_y@)2F>|;O*+$KEfMXcZR~h^i}y~k>i1kf z{!Z3!aqIKT=l(k9vG;qow|jEi{`K!3|Kiib;?kB%2Cc#qTrwjDN?t>j%>A%a%p&oM zdXcRPsmf5EoDx33BtrBY5vK?1QSYes?_$7nLvGyCJ8nlPEJW8AO%@rS=V{y%@{zyJJpqe8sc`v);;p?mM^sbU~@16c%@ zveB5!%ETpTmLwnMgE_E{qG#*?YMpIaeISJckjv+A`#w_>H7;PaI?xs%0ekIhC zT8T>bk=Zgi-II~dImtbzb1>l1_YPK=ABTnUfFuc@*Bm`VgM=Hik`vWdVL?(v5=cp{ zw%hh76e!@~>{Hf;u~h1gEOjv{Q=8?Wgq$~VM`V!25mJ?eK$MkqOy;Ora)JK}$2xB1 z{KQ%L`0DZy_A&TniCe}-IEsUoCA0`#b*P}KJTAz`|_mq zUS{d+_}R9s4*A)<@OHSlsB|=XKEY zqheNf{&Ky}8ke)SvEV}e&2ys`DmazReaxO#x3-b}c>j3)@cP(3HJLYC7yh`1HoagY z%9MCJu$=36Tj9!2OLQDRzgv0AZ-1)~5q-K18@+#i??k)tczb{StjnMO^X*f;{P1wz zD%VBGDTy@z1v40qutNp!hK-wAX^chbR?ZJ3#K)b+9inA3buQHO+=^vd?(iP1~( z_pFFmsJ6im)nDcG#2oFSl2!{*I(bi8WqyI25W7)B-+@SE1Ti0;1wNUb3bB+3QtC^U zRdxD!{kuP;5NpoK?v}#`2_)bpN{xP?suFV`Yr!rB=xF)7`nVtaa2ro)|>!y*ZT z)5DMZpri^H8?q=9SA~Xj)p_s3Fme_u>d8(X*QQI(87wTT6ywO1&pf=e21I*!DlT;r z(>y&~&QJAnT9>swK5lEn!r7Wld5|%Qg4i=i{5m>aZzN@Ii)v-9MV1L?`Jeyg?;^&> zQRY6bQ?kOGWzp1GMQR-6$mtA&C1rtmhS;gn@R+lRBr_>hu8Jg`<@~_QS(<7dyb5Va ziqwV0M3pOx6c28+1QX@V0v?v@MmE8W>EP*l=6PgLQq4d*4QFS_*u(tTX94=%dcuNd zz~``GQ=kqYc~w4c@U|^MJx~kBxFt(O`E>Hb;L2gnM9xu)X3nA%E>(?94i@jaG;Ak6 zJ~-72B1;ge1jC8h#}Q7{3ewb^i6mw%tL@#!eOrVvfz-NYn^T(79!~5t6DGnK?&%Ir z@ff*7i4Y=5C_p>Ghma)Kxqmr&vE(v+aTrsOL>jbMvMhzo_NlM#sI za-h1>Ng{-_Mo7I-s??Sfu+my_lOX04vgE?Nq=cBeXk-v2=^BKHDZ$Q=!%%=&NNzkM zmj(T1L{u1a%rM*cdBDTpr`sI2(e85`o_A*1&dHKlBzq|#ZLQ}`4~zIH<*YKPP}K~p zkw&^DccK;ZLx{jDQP3Ea6gkNgg(*fdC%}}^6Of3c3|<^qgM>0rD%s9byl#>Qk~Ke~ zJ&+9%6{gexFF`(E-`~Ez|M*M)Uw_&E^fsK?l*Bc?Yo)3uGZ!KuE~QEVc`%bKq_z0n zf=DYRqjF0>rg(Pe%wQ9rxBKq8@Qg{n5)oFV+M<@0he7gq+wb8=H({DF%cALqWF&!u z&Dp&yb#S&;4$n*wsW2kF)_yuaJY49!m3q>LwOvjqOr;8_bFG<40kWA)Ice{QH$7dX ztVNa+mnp#nk^jf<{>o-vlfQms3`}vN6|F5c$Q-(+@0r3jW2xd^5WzJMr#8WAN2j*% z7*%tXSQjX5t+3L;g%so{Er+k0u#g)O!xuTjyZ`P}{B-q6$AJ*Ts`XS?A~^{sZF7>87JEd)!hSs+^rmEb?4j<{7G?q#hMHJ0jkSi^v9A=_L zEcH~l21qD#-$OX4YI<=dcwypNBoEfc#n~veBJM_)^g&EfHWWXONUpxtG%;R|WO8q7 zmCGZ|VRxXFT%-&_f-aT!QGCpHiQ=Hqcu(CB2giRTk&- zV>?Rj>8D+)o?^LFe!pLjpx^y)mgDrx-`gGUa@n31EjptANWpw^WS{?oxFUyEsx)5E6KI+P9a8jj>SAU z!lSTf2!WO;h2W(GOJ$@@=KGJ3B&|j@yU=)N{+M*`L)j0}ka|L0CvD3z<@A(hYXgy% zwD8azfm-w$;phkUd!O$_>upw#;+c*JEMSim53-`kB?vQGB*m}1dNRRNR@91z@BQVU zvd8e`Gy+QzIi^j{8kXQO&{{1l!|9Koa!TdaA?Fm!Q#f1aCl%&J~QnU zP9DU?5o$e2*~7S@R?Z0~a`_caL!(R<&TNbN$kPR2Fp|ml@o^tN{`B#m|8f7vQM1r4)}KA`y-7O3>|rX8;qd<$*(1I)=Gt5SQWxvT1kDfYn7U!VD?vd23{) zlnp`*C>?j6)4J7=SW8__4;(O!%IxN-wD95!mt}dlJkFzwZqWxVDI|5N4=n3N9-o#| z!&0<8@J5r`LUVv2>54d#r_Ib3bD%8k)VOic;B3Sl+(KCX$G`Y*57&>w(;_vg)B=go z8AKvPf%fDAfQ2i^B$41^xXUOpBUx!#xG^l3!aynKO=wqjB1JlDq9`MkGg?zmUhA+X zI?zO-MGOH`R-)uFQ zPHuHQL4)qy+E#Q#WL4&+Bwz{5D4c!I-RejL3gGJMtbIDCd|Yq6Q(t*myvO%TDwi9PzFatwHH)-(BF=E;g@Hz>ysZj({&Daohg<`*r+MN%v85;qus;^cdFf5NY&?x~J{^7(&1OhQ9UckgfX1wBP^ZG5lt& z{^4&vZbiQP&FL@8%U}IP-L_?nx|x&;AB$7dn=_DH%lom6|rj;^x*m1jc8)hHl=#DAtbpQDI3P0qVZ`!xtD!RYD z>2@MEI%W+(xy~ckrIamV&#c@OAP!9WVsfe%cNTTp zN469DL1hy*ijiD-rV68IMIkyQySli~+xz_b^T&Vrx&NoX8^7E?%t4?SPE5W?NwUbC z(~(LwF;44ZaBj&`#K^Z46T9_sbk!2VPE5lsEHi_WmjXy8s`w&p+e)iQg3lR*Ic=v9 zGO#9gRd5EQLUU~!lR`l%Au0!KRRSoiWUVU8BF~Rc+lkIE%gVlNWz(rt1qLM+We-4& zvmZw{qDHIC^^^<}S*Qq?0c)&>{Ez?SUm4JQbQ@3xl@MY~VIp>AMG>8rt(jBO& zA(Kmq)JELz!FqmtDYO?3s@qb7NSISr6`WBa02N_OB9VL#6vkja!EZ#XL8$EHX_VqU zGcp5nBzMb&{Z8YEW16vy_vq-9a{$)&jPAM<(mWAt84M8V%)(?5x-Asq>_`ZhoC`74 zhK{_L1ThJRvsAZ{sD&*{je}eUqfXAcP*N+xazEN>p%Da9pQa3gZkySN8B!&|YCD%l zV$ryt+QaOYOB;EIKGyvvLL4JI%=RZQNzOjN5$o z3x9e#t;^~D`MAmTR{U{&IA7%L%e-IjLuokxWk8z0>-tOj;{A3D*)DCVWBu~QQGHOU zA)HGXIwlK0KhSCtG`_rdzQ`HvG+Q*RjxVp{w(oo1-^TTiKV9vy{`J4U{KfY#=W@Dy zmGa`mH4l6-jZnoK1t2}?rLj@&tqJ84dNq>|H5a~8S{;KS?M>-0#p$ z70xUGV+S=Nr#KLWI1>aZG`Q;4NGNA%S>iXMnaU? zDMT37`!VM0ZT#0)`w#!+?H@imQQ6ItqmoWg0f9j9a;~K=D~VcPwsUVLq=dj>~zwZ2b5v53-!sURx6c6AMiu7OCJKuo$`Xi4d1XbW@gxvQC^H zaC{}IBn%(&KmFNXrN!ayEXBE$>hq(@8HIF)MXodh#f#K2Gcuz}*)j%*+=C)Kga|aF zU9ygR+Nacm@p)=Il3aPn=gPT1VJ@RJD``&{S2AM&nSTOd7(D(7RcP+K$WO zcMIWV?5J%<_ynbsk+fF4QcR{mT?$7%Ewxqu!{?pFY>w$z#D-OKnv+sl!GfaMd>AXw zxky+zN@KTLRU`~X#C9sBh1@N9WgSZ%j5SN$>I5^17>YhDu^)5Db-Tz3Iq&11(WHHM zITfcP^UK%!`p~v)g!t*z-H(Ug@?+O!tGJmwMq4-jajT&%`>XHz5Z~}}F2$0@b(?o>79RQMfosyP!1W7a`vNj>S2?IXA_N1!lSBse*>dT{ZZvQ*@0#p6rE%cu0G z`T8|%tm}i2$9;Hm)l>#PW-fdjP=r!lR;3)JWx-N3S)itIu3Wf=&GlJ*2cU{@r8E}l zNpNEU%>x8T$xQO;T!bi*Tm;J{&D{>S>N(Qw2w?a7wEGA+j@$7LM(X5DCE_yP?(>&l z3P4z97`c_Lh&yrU43rBb3p|jLM6?itYf=%$hU}SzBB3?MARtObCixAh0z-_{gb=w3 z9n2}>Wq1H7!jfEy5U41JLpj99Eca{w{15Mc`}be}u(usXx^O9RbSe^I3@EXa3xoyT zkM;2s_jh(8DYTG#s1y=qs+paIj0!{h7)Ext6^?!kUQ0$_g_zJ5HU)vZk3Pk02y0@{ zvXns?AJu@f$OujJ*-JfVDruft$s|5$aVv!L?gREP*BoBa2G{x2tJKfIned$zSnQ>bS*N>ycN=A(y2 z68S{cKs!a2X}e~skOia)3)YcRW+^9VDhp0a1BoBOMIO!!B6E|A$^c51BiT}Z;BgHV z5GPwgcs((t@k$x2#UjY>u!&%Zx_gLN4+Kx$1cr|2KLNM%HX zz?n-_H?P{3W%2Y>3|==(51r(}O%*Dflo3LxMQkLCN)FMoF7SgiXHq6bMiWt z_fa`nRY!Ny5QzvY$=h@altNAna zcgh>eH`KQ` z!Aj%+hb1AUDF?Nh?M(9YVDzl{`g{hx9dB=5IRYgqsT9gk6skllMp(#&mef&GYH6UU zlEkG@rU;)($xcbJR`DKKg+bo4p16~R69m!41G z5f=D3#@Of4XAs+*?kvXhAl(Us{>sO~*O4Vd3g+UFR3?)iTxQGVWX*vkN5mYJZ zR}zDOj0&QRhytojlNg!X8MilTkLeDsEWu1f!Z9I*GO2)qeBO`G@#V|M-~QD9<3GHA zImR)KnB4|PI*F#Uuq-PhCE%W|@Uj#n`Oz&%Ni65-{K>|on8q4CVHuRQEy8u0IU_Pw ztqU`6`g}V3j0_ty`V>qH0veX{r|3uc*dEWB2oFB3tU8S{GHbg!!lgefSKR45ynA%<|3|LZ^fHz^`S z>{G;@S?0_LDN1BULgA*u6hawIxyU$n^5G$t&dkKYELw$GmrH4M@Omx+Sqjyat@9e> zB!m=JX-SeAbnng&b$oz|m&(Qz2Mcq|IPNaOJTYAyiG;BSJdp!_KQeeu4)^IYC8k@F z(4>%z9ttiiDYJ;t0T7oaK9k9FP|jnibg*!Qd&me9pCb|hEkM>dV46$>i?-2yc-@$* z=r}HqeoUbtOOgbL9R?!e3Ph?Rg@bwRGF!rGb5GS0Y*SdkG_80}Pq0^)tV~HVK9V@Y zrB=1u@^C7c_uFm1yOF@d9cEHA?=GyQ7!9!HxzS!M4r=nSrh(6 zE7@Bg?L_2GkdeCyZ`LgPEAMNq+lgMUeqcO&TEBf<{iEvE4;xbJ_up*yFLFO{qrE=r zvr2ua?>`Q&SAHr>A%$ekQjS}?w(~=+`{yH{?AZJ1&-I!4{!8F&X0!gL+0RUas2%Tb zV|!XIrQE)1+8mp$rjI8f!I_zx?6( zc{{I@MK~oS!w`0o`~z<>5L8pOIH?-nb~;Y89FkC9WPd6q}w z1sI5<)XSX5ymQb>${jC0H;v!Ra+da3bby2sq6S(Oo*d*!s*{_bXWe@6jTNU;6nnEe8?$AOM9$;otA+uy5-;*wco=vmwtdHnl z<_OBj-pO`nAFoXrYqPzW`5TB?*d zg;QCzx)x?8;mo31)+C26s33^Yv~mW-1gr&6UM;hM7otc^3L!%TXUq&x#E^=;$3TX; zp6-^Mc+X$SOvN!qQd&qWsZ>%ms9C4=EC9$MnwhG;u62gs=wN0d>E=dUn#Rlovw}FC zkT7W!JC(wWEpA6Dy}g1%qzH@HFc{9K#d}gA&sHo^!9%jtnl4LoGnHg63d&3g4pq(} zlgb6OdoA!th_#g{G(t9NC-e`$cVOh+qblNIovQsly%H5=Ea5Y=Q&6A~b|RiOMOYDH zLs!+zW6-f_1;L`oTQC4_ntxi_%hcnSu+froz=+@+E-A=LDkoL*O`#68!_)xpe z*V~;x(YNQa&aE(CZzd`a-?it=26nRdqu&O7|IK>dc>)H%z2$aVE?&O;+>fHc!p?s6 zbnob1GGtpr@9);B`?;QYi+d}G&(}e^od&1pwZFgixsz{8#OwU|{eIMWd0774zkUAZ z>G3(1bG4L;+n@`DWmT)IeZ;Ci<@Q}jhP872WBSg_6H5|zDEB>N22r>$FkDJT$_{$S z0?DZL3NJp5-+uuRS-q^ZjIx|dL#oC&xBP=t5N)CXuGQY5WVC7Al8SI9()_&0o~oW} zrJI$N?M@O-MUz8V@&igGhf2lqm2ef}q~x#+Beom?zflsUW(*Q-%d)iK)6;SA{r5k8 ze!b?*1f>tKrYA8cMbQ?Oh-<*=r*UvVKI(5kG$R9yN!jUM-+2U7j~vX;fN?G zmvla#>gd}hxI#63Yhp?uVac*^aY9LzupxD&42Mu+)CK00ND+=H?wmkjW=Y1cxFpqT zNXdkT2nj0*V~*+bddKVM_y71`#((*G&E@5YfDzXW2Wt@^qo`7Pw#N$$Yg=h}o_TvX z_io_~VxOG>>obcAPm&fM=rMChIZybijDVh&Z9!748~EY31NVppHU@~&%lcH#oerW_ zDID%hY*8ZE=8<5~BwZ*?TU%cqA0OzO?>{}9PUmyB%lFMbf)}_Mi-(lritt=*_!yO2 zwi2bSD8@X&1W|I&rtBW^oEYRH|I?rUwI-YQMGKLXMhYh>bPQJoGaVC^VG)-p9dq=E zU|tQ0@YD_JM2j}Aj7ku3-L|3y$y7yHITU1}MeG1wAdKv+CvxK?;9y5mk$Fp>UW!h4 zRb(Z65M?IWH10Dp!pYqb_kKl(O`D;MjX7ra;EYj;wQ#_r=(OMxAu1!Ia*n|%0v2-j zk!4XfFyV3rB}AZGVlb(%k;cMR;zlW<86#Lq%w8eH>Xs@Ys^POaSP2WHr?b^0D^)09 zL&yO!DrJ25vNWseSF|))W$)oUg2W~S5+aD$*3%Cs+V}nId?%jQqZ9GUVMd2JG5QD) zb0{V)3y4&GrXVp+cnbPCtv6!TRAFD^Zn+B z@pje+wYR)~z0LYeCnr%*`n}Is=_KvMb>euR77IVoDkW;m+c7WSw5?>`r(J&h!{@PF z>dPhG-;O_i+}k(ho9`cf&~JaYl*^0y5pE#zd}2NjQr+L8)nlsEoR1uI&uq=?6V5R<^pfSX80ynA5Wo@ulZ(JTK&lKu=E#oTsn&lH% zJxD;L^*|{e1})fQsXi*p6}rZRVwy>fD~Jh}LYBrbu*xD0ZtN0H`nx$F_FcH zW8O%KxfD%ZJRW~@|Kp!-KfWFJNg8oaDqxr-CsEN_iJ9}Ea8_E&N|an0A4g#U4-zFx zfdwYk$MC7gPL(i{*+`c_VGdw&aza2tJdL)@lzk@>BY0|tnPEgm$31gDaJSeyx_dmG zBQs~Fkhp|osg$~nkzABGgrl}%Jv;m)*-n(KN-p9Y0XQKEqjJfFZWM4c#Po>J^@Q{aC&{$%+wA?r?zrDR zNChCRS%fhd6bxYGEZRsrQUH*;hqhJ5DBJew`BE1D=K1pcd^xw=+OqJ7T4-K{lt2Yk zkO2+1Zazth*(sP>C2`>d5!c3=4yi&` zg#{i!We*<|j7s~=m;^?vY$LQ%bRDyjOR&$*+Bh>DnS`oI245|$u7xM220Kv@QBIOV zbR*^6Cu@Op6j2JQGNO?Pgidnx~>MG}xnshIgcryNbZVB zqINrOU#G1neSBFz|NSv96b?;f7M&-M8?E&o)u8rV2)Sz4BsmRJiLk!FI!)_VP~ zAq{a#RFJuxFguq6bOIHNY4#{~6BX1G#m-FVHyC4&xD^xU(?zybq_n!Lu5%WiucDK( zs-~62?ZW#}^qrPxOk{%7OQ|zRk&{-*ThzwKor@5h&D;mua9#gn*}&@7A8 zMhS3BN`NdF%AqIN05Y<&ve;2&=N0qmpXcWvfBMJI^VK7V%Su`TUWl?n1rA?JmLf{N zROal|3c^?mRp#0lCK+%A-B23m4e~(Y6uo#4U0_ZGup`}Q6*r1W;Xx%WM@G!>BM^QJ zzYiZHN8ozwgC!5&=e{6 z(^D(i%t4fqBe>R>ooG!qO6BMzg-fCj)FMO)t`u2{j4xTK4_x2gfB(np-~7Y;X&;l< z&UU4(x!cGLq6icbNzBM=4&nIwLYBu)2D~$Zyp{N zd00!U))W~Pim-H=#E5D0$k{Ul3kEN`h%+j|QyCzR7P*5q&o1fQs+ft(%0>=7ZlUu|Z$a_bbGd%xdl z1;ywA4wo&CSyar-NzU+8l7Y;OI0!aD zs7aaQ^q1ei{2%|d{OND*U*hiA-%O7FarpY_94MVhrpZYp*U_UYX$IX77NH1D0BtG9 zIOrbrp$@ypK9s7_e%pp?bU!unqYn~G*-E({4dtUgmj_*s*Jb#J2$bXLH*5c~-!O^% z`TNt$Qrg$L4?bS^w)u8BE$_1%bstA~O*)^bex(r@IfBYomNm+8MJ!_obElVw%1$xw zui6z$O#@9kb~{PA7H~PPvWn(PSG)Xyr7HtSZ zzvta&9JbUvJ*r@7!Ky^g5kyDII(L`+&_+RxSRj00qwbY|@_MqU8I!6rbEHe|;UuIp zL*bdLxdkm?&-D|>pt?|+Hbe+XLWE%w_hfKgBdfr(Ed6Ys|zZ06z0NdZS~@TT|`30vQ7oE{#I-3E+Y zl9f2-z;a$H({^d!egAxUdHGcP!Y%~nUrXYB&D|ML6QkpRg8#@ zcp9~WrIqSJQO8|QMQb5A3y~-niCQQ}Hl!}XhiA(eX+j>L5^aG6&XP9a769a&Qphuf zC=_-CWq5|Pt~&N3k#`dAar6-xj*Lkx!I4;+s3}*UqnH$mtOf7_W+V^E5$uPaSt0Nv zJyJ0-b=pxDo71R7A?=4(0vOZXCd!sRI6W2;P+}C>Mwm`xVdrEarA9t!DLQzBB(sc} zrG#8yPBX$nDWb0ZdTn(rlIcKFd6K{UKm60n%g6nH{pq;N{eH}uhbW&Gz8O=kRlt#Z zDudNRPK;_bEJ)K1S_mH#ZNfK12AM$`1*sj8OPv9_&3D^QTTpeM?bwlzWm%4G&KW%P zvOE>MzUghIWv53uJ=FTO9VuVO@$O?i>!q#UF%#f^V_IvTYWwN;{7z=az_(?awE~BF zl3}xls6opd(jD&ha>)#y6P9D=@40QvBQ6gcU27$*XMu|lFDe{F zLbgj&#tF=v7MLl_B&2|r9AGHLM~FC|)kaW`eu%C<&8hml^Gt``#@wwOW5m9H8L(r_ zAhR$gL@uRKTjG9{R&tmK?@63&8ew+XK_iz8de|Y_}Pg|A*7>Z#G_CjeI zc2K08SG;!;S60>v?`V=;P>@uMge*&0#1AhUnGq2qhjkf|LqZ8;!KI!n< z4}<)wtV`mc(?iQaLK%^fuv>@72nm}~rBJIIm85m!mv0|m&f96R=aZgJN@A2HYK{S( z?ufk$^&ZRw()GMb)RN_N0yB{ZBAL_fpd~edLV0I8OHQYh|M8#v6-!8~FtBD@Hj2Qy zTAvl^w~>-%rYEtQMnp~qr>Eu&sl*WTFe@yDNbAQovS#6jn8G2dWCFeEu8 z5fh?hbCQS;N&`n8nAiIj3olnQqhd@XS7p)*5q2=!mtX zm#txz)0*fpNZlbK(Yr7gtvPK#L1xaPWm!Do@`S#hn7mZ5q&6OrB%D!7LrYJsN$Lnm z@k}brOo&G0B$&Psd|l|H`yw@?6fze0k=oGTIU)Mthj)6YJA9%e8F>}@=SkYLt z$nL-V^8VUyQ}X3o{!OcM=G%@raegQllItrSmX5h?g&{Ka-tQlNTVD8ds$YLUce?i} z&&&28HO%g}*Iuw~O0Fmew&jQKKK*(5_BS;jAL}$49kp>r(7E~!g1<5LG3=tacqG?FS)bP8-<`@Y| z185T0NW`z03Pt1{9+?G^Nx~GFfS%#*Dan=0K)1G4r~1qP_dk5xq8zg@7UP+`h=;VL zr36*$D-#QpS#wZHMg;}8l{pzxQ6P~ySOOssp%{rmLIiRF5}cMq&M)EviJ%&Gow%U) z!1PJOV~%<4(QgwT?}XsO0a{D=&hA)Fqu=$iVp1X(rZD51*Q)6~L_k;;aN`)M$$&?M zYVq&_OE+JZ{MEdPlbJE6geD7wg*g%d$8wShz#Y#-vlMm|oAY`dKmYRnAO0|3t=!F! zq2&|_X3xqk)#F~b&79}Gx2=%VB0`kILYqLVxp~f|RUgr>qX^s8Q*};5RhuMhVIQ>> zp)BOy$;EuAar&Gzjan<=Qmd*)?{!ha@Lb5}Acs`G+ri0>Q$01x^W*91;o+N?^6>Kb zc$QX}w^MC^5#6p?Y8ZPAPeW*0UmNPyR0?lsc}q$m=7>meGG%14L;!(uWQdT+|NWo+ z8y3kJ1jqt+26^tCmpW%~Q-zrc^TDrS$r>Zt76_ze26*?HTIk&D>KnFSjHsJ7+y?7$F)ypZo@}N zJE-J-jJ3?ng@{+4L8PnzDAk>sI&vCjT^b_E{dA$QEFw+-O=XEe$V^K$O3k<{aZm~} zq$tw5YmG?Pvd|nWW4M4gI2@A7#O_3ks;jIqvN6-jK0V1vq~DB)RRvyZnAfQY5-9?j zPk;5>(?9=h{=?rN$8rD3Zugl<>Fz;=Se&wuFONQUcVPJ>buyI$=2#)@p01onP%R=R zw~<_RT}qg}?}^ImW7EBu4?P99^GhkW>)?ljRZhC_XW8TZ%dqoCPjtaJ->&@rF{$`+ z(%iQyD-{|8TcuT{-*kT)ce{SgJ08!!dwe>N<@zPxksk z{V4P0X=^v3$oK0Wq7PfGAE#pu=cBKJD;RMgzk53U%fEd3?Wfl6m2Pc4&#Zb(FH(KS z(~AoG@HW5Xa_Rg~uYVhCt}k(r;!nZPY)+L&F4LaN+wW!j9NQ0>sP-0p_%BzdZDPU0 zSqsZnRT?v?4)P6i65YXNL{%C@PAbS*BeSrDWU$r)Z6gN2aaex*!jGRU7vfs<2I0uc zW=W|iDKouXt-IR4QBxiZ05r z>-B&8{ml8@b2**L?C`Kis0eemwbBU{Rhd-+EJa+FXN`MG5xQj|qT=X`%~OeHhJre% z1qYnj40RFm3=ew`u;e^Idi%(XRGxkCF}jy=j5O@Mj}(d+yJuoDlQWw!Vl`aHDDG|) z)|nVp5nZ`8@mQLsRVu1Tu1GTwNd%aZgeKA?h?pZR+?Wf(BOFP@N7537DiX9Lfy9Ce z%9wOHe){F7xA~v{=Ka5Zo}Z5)%Ql8H?gq*LJ5A3*JYbiXM@7+bE5Z}m7I6xu~18Dn-GhAc}cDEt(R{iJ0ly zw*8}z9MGx>Xny7IMH%~U8AyeXKzN$n*>#l5wv`42wJv1H zrc4e=+&Gz~lHDOo^x>rxlt3hl{13nRi;M}cP%E7rT5IIPn%BEZ&Shy~PFzC#q`@9k zkeLArz|)1zi1MgXxL_g5wiUbST8q{qgC#{Y%LO!3B2csqibPdP%V6kAJUH(_q3m3Q zZB9vEs=LBJJkK68MS2P!9Q|WA9*#aNx*b`=Z1*;z&V+QwgZv zi{iZS5#1)OtyRJiAU$>~G~04UOup`Uern@`S!Nb*EA6}Yxz~k@AbX)2Y4xGJ&{2Bt zgSbg)SsgiKx92?7^;w&Re2jfuc5qoYrOEIp&t~bRN<)17bo>(YR$u3qFPDdB-m22) zkN$c)^t*U@I;-XTwco|a=;2A0u(z9j-21Tj=4CB={&JtU`PCjC=#De@pZm0O-_1Aa zAJgcvzI^-i&mO3-ZEaQ_7*Qcq@2 zg^z^P_{^s@O6l>qTz{lCC8WP)MB1Ws`G%HKE0eay2O7f#RM4jNS~93Pm(?xE5KPI< zgoRbsQ%>gnkF-8VAnaFbWLe73SUyqC7@@G_n6zq6(80OPn2E|fSV~giM1T>)Mv@yP zESq(wszRMh2`nlu_|;@><|(LxEAb*I%t^`_#eku5TYt07H+g^mxb-hT^>!*tu})G% z$tF!XuOzh=Nzy7Mg(QV23rb^J$t}2L;miRSNa52WeRyW7@=PkkGn@<42wsq;V}y%m z*c7t4TXf6YjG4T@kHgSMb_JLvQbEoW!chbOYs(za7F8I*JN2Ba77r*QEj=Pwgr;Od z6dYaF&{O1$6tkpAlIlsskU6jk%EtYkpa78)#lggtM~si#*W6!!{QDpI-~ayOb!KFG zP+>=@NTg6%RLr$iiUfn^NM%xKjlv@a%qHE#I75tGW_MyDD!DHGDwj+!`M|9Qw{X+p(~X=(>)5vELjJJe+i!k&{Py9~(`*l0 zWvOK()S!__AEp6*F2_1>7frh+SBvD3~xnms7ipzDn2+U(rOYbXPAo; z5^yUE9j?j&_hlollX$BY1u2WT*F+Kpk_S?n3&(H~^&;?Usu@-hcQf zmxsUpvy!>Let!MW*Vk8{4m>RxCcDw&qFcHBcsDQ?Uc!Bl#u&~EtZ5N3zZpvMcJV&F zRWG6#QK^1@k?%2~CvtuBGtS`n$lA~I8yeFvD>;FD3)|Nk7}X}2s{ zdKl)t(;gxsGtY3(y|;$0s_yD;bYp4)0!S^IFeH(*O;Hj6(zNu&f7WYxS<4n>iY74; z1khu34R<)_WM)L{z2CuQKaU|nNTseA>M0Qy_Xt5U115tE-ogsl8aT&x9vtr2wg_vF zU2F^;aSF<9U7bS%OQJJw_N z9#A^FU%U-RA%x(-lt&dI0IG>X+qygAu%V`H8@qO9E?C(7{&v23_44K2?cK5;COOh5 zNa(G5)xNq?2>BMSn@TNNmpSEJIhl|F25JH#$b@lmqR=DJvjd|cAYfFEci=K0^S}E1 zM@WDuJ&YYO3nBiBXc7FC}VzWddWSs(0oQP2twBhCG z&L9}Tgn}dSbV|13^ui$(*i5EON{x&Z)zr}vrO_dR!4wdhk~phs%DBJpZAc%~TrDF( zaJ|X)@lQToK0U?z%liJ8@BUMJe+4`yzjhcBIr(t8ST8eAgc8Za3xfeArvz>~2Kh3{ z^}01kSt&*8f#{XQ94c}?%@uk>VRDZ$Y|l5h$*$IH^_r_CzXl|Jf8ES|KFZCs=ye9J zXa*(Enf0p_OMiMgKjM{gesN6Lrl+^$8Mo^mN4YKeZo%`J-;b@&!JMa&)a=~_jA9a8 z81?E;kG8^ixS71myLamuo{?dyQy7k%KDb+c>$g96c|087VSnxCCrih4d$q%Nd}q#` z>qLP*7)DEKHaT2RJyz}@@Ri+sXqHoZ3mGXThf3qIUx=Q5ZTq#gQ$OC8S?VI+GLYP# zAS>BRef_U>K=;C{XMBxpuPiNdxP zZh6TtFqjxYoHhtx;^E${<6tR0(Ag{47yv-cGuMjW`ECBaALFN=!6zTVr{9myK7}9r zz`py5zWQXdTRgu@jGiWh5}$oi?>;t2w7m(MMvVO_-oAVM^S|5w=AHGf9R&+hNf1V6 zX{v=?1Ie9L1PzF4iaarLR&p+^O=}N@Axf|;-c)fHtVW;-gE7?dVG4_|6+3Yy+Z1Dj zN+N*J#-)xhFlY?u)Pb!diG-24FQpzQ`QWop?v{LdAvZUtS%#DvHVoMU zcI%O=UPjw5D4ddHijt6|A`c`X2FequQ*_77K4YvA3AutWDWeZSkA{f{|C^Ve(NMaX zq(`*QWp?sDG)E4J$Q3G~54P~BqCz;Q2sMK`+jR$pfRtkOI!_UmwlYstq)6h-@T~-i z84`LzAVvnvlf+=2z>$3iN~kr&0fMXoUkNhR8vX3Rs6oB;QscS;3>dHu96iFI6OZ%Q zk#x6KGIjUpIU}ZuZpd70FfkJYQ=W^vA)-VK^X#J;VK-q65dseF5J+fCo|Fk}m>StY z>AnNIgJIMKVHiWC6wEpZ`!$?_m4z@DN8;8X5T^=U1^0}_rc7IdAl5bNOyET9A()G0 zz5o3F)gS*>jiKLseg3QS+qY$J0OnQ_PK!w%&R$BQT^dLbrjehUEfe)YTQ6y*0^p%x zP)jNddk2K6@Ypwilq%tQixy;R_=2S|>i&KoURo{XCeMVtx78<42gq4wniUOs1jF4c zNgkK?VSL@}x{0M@IhLh3T(8@pkzUx0am=&q+_kOfeABb#`#LJmZO0ssMt0SYh+IMNs~MKDIklG!?x3>a=Dr%nlh#7zlW zxQy#+>*!d66XXPfB%BD5M#+p2L}WxT3|S!}(qiF^07T@DjOZ4@0E|A+w~*OTFaiS; zB^IdJsoq?#?d_lctSM3;q6;Rjl7v#8PJV%!!WpWhzT=dLk!X=0T$gaHA=kx9{+ zyNRTPdX996QYaLWd|GfYHXX#i?XF-z(XY>VW3jDUT&}H~4l2Xkv@7r!kbU^X7^sGX z(5>;QYJ{2*vBquzy8>DR5J2iaV_l{n{wV+9Kfe2e9~@6@xj)vIA0Hp)`9wF%IM%h) z9d3@jP5{iG{0@KjL-~y#q?=0DFXOzbM!&9azPSAI&HmTF7;nK1$*o%l2;(FK(%VkA z_k{Z-4U?dBr^{nBwjD8 zMq%_il>|hpxuOoXb{4FoD>y+OVA;gAJBUmb@8`qq2X`+|)9nYRyD6qLa%Kt(jBbW) zrH<~Sxq2$-mUBuKxe#*7R3I)egc$(BS**{28)2|2Y}c?s4B+ZClR!A|pZ@0WMJax{ z`gBw=^1ch7&u3pql9(>Q+I33kMc140U3emncQZVI~Mb z2_ON?l#Fy(Kp2vA90kxJCEs_J6kx#aAOR7BghnuVGam!oBOk!~XhF{Au7*3M-h3F6 z@4(3;Wg8KQnNkdb%&xKIl*pQUU=eApp=ZcJ!$F9M(HrrMq@H7!ZPoqdSBtqYY}j*GkuhnC6@Q z-T&S9?>;JV`TFwJc=t7JEw;zrgcxa_NC!{~G=psoOhLgTRA9+zAR3phj%dUp92tYd zB@n{KW>-r2B<4C+(=z+%n5D&aBjb^#bXOAe+wED*2EUT3fj%u*fV!E0VU1{Zr5E?h{;RqZJU@eAKRu-Jw74fmU)OD(@RaF#(et+TWsr~4 zebzUs{QR^wjWDcztFInzKRSK*xgYO~#I5MxZTxX1NVfrWLfyo_@pNncg05eBR2pwB z-Q(JAnG>7WhL}u*8_V)F@V&N(_it_8_pK7P^l*gbP-)8aHK!SX$W|!HF*|1N17ZWd zXAT2sG(lfz{|ZZ?R56V(=GZhXD49JlwJ`NPILyVcmhi%Q28?hb^Z@ei$#*Bx;jlLY zQq9gtQ%Ie1FoQ8WU`a6`8iFDx1hgR3E-=3!YO&n#FzylxXcI_bW%cw6lO%=Spbt+ zV1Y29(J3|pfzg8##R%^}5KRNX##mDVkAAtdt?vq#^X9Nz_r32OSqKYI@RY*P_LgdP z8vvDJU>hKeh|P^@vYcJPrWp?T?&H_5|C@jQ!5{tR!zXY6O*bE<(_CgwdgZ>tP|{E% z3ZOjO{VV>?hv~)3awKQ=^g6We*XO5a|NFmt_ZMIJH+v|7QsOKCPT>H7H5kOLQ&YcQ zAp=9yD8${IASD~CrHP1?kR+#EEsGovoENYb#si{TTaJegm_bvJUcHY!<W?gFD5 zFaQfuP+iCPZAMG23Z}{Q4j>kAk>T~ktcFo!q?zT10V)S@SlC~Ll{nTv4qqT zj0*|xm=P2rAdsk7A7R1H(HcgC2L-4B+Zv@{6k#Qr=4yp8Pqn0(`wkSsN|Asv8!#&% z6O71cI3WcPp_Af{Hid7_GusL>)4l_iSTM$5Kpi`D2PD6AlH?7P)zZ@TwP9B8j6R6R zb1O52j)llj!BKLQC&z35`P$VxxVlWqfF+ON&3q~>7KkL27>6O&>Si!ha-sz0EGQ({yY7vg zQUHvu<86#%IUc}N@cL|4l_lT!L5BzILltk+u~&bFODFW9F^NV-IB$K>X34M&&gB6L zG-w$DE=qdy;#i*8MqIl#eA+@@yew@^up=U{JJtC5mvnw?@2`&=;fJqgf3CVk9fxtK6`yT@3m!)cXo5I?MCWm>7m&BG2g(ZbZ#O~KELW0f%XmbA%({Df}lAf z`VxsEPdbd>pM888U+??11tQ(NigY;eW4c*T6>KJWj1bc#(IAC+4qzTi@gB;96{`=x(U}M+1&7j1T~RL{B*~BqAX96E3W!KR3^AOren~AOeJgV<2LHfSP5T5w3^?I1#l# zAms2&Fv4AtnG)_E-91gQUo1)Qd3|n*u|c@W^R@vv3b(87I0Qk($q9sq4`B|Lv00B* zX;#|+Y6EM4v@G{8%6EVBhoArHpMLaPrx(js(>>kYr{g64gnekUrYkgCpWpV41|H;e zn;-7x+e1#83h-3?E^i-xxZ~-|fA@EP{fp_7HuJO8e@;1j9CP{5jsF2F-Wr8JLp2;WAu^>LMS*KE1K-13j!D^D5q2s z@BpI0nRS=~xT!%=H!yT(W|-#Xxa1f2ukLT+<*N_x?r7#X95Zp?P_!7HJkZDkOSl2J z%(-AsbHd>zSwJv`3xrl+K{se4WFqY72woI}1l&7XcG)>9!QlV?^B*~b3gi20iYwJ> z!yE>}OtHJ7g1Rdra<(Wn`Wl=;4WYS+7*LoaA%T#ikVvj+LmyOxNiYEjP`%~YV!FW= z0KkNvCouDdglI{S8MUDUn7bs@h`s{dpsk=Q4hhTK~k9S@q88>281DiY8s>+5fvmh^Ep2Ly^l`6^Bo@N zc9!*<=gWV1e|>M~rcOyJ@zB;Ik}#?QVGB-R*TJ03$ATggfnf0~UVY;-eD3*VMZQDW1sSZ08}oiFddS-*Y<7e16%$76r*>$a|ZRqo_5 zoNpc;zW-aVK5f&>rF!k_#rw$f5netZ&m}*r9}~YdyrK0Q-v#8$ZU<`%#k*K;bFFIE zl#W3`(<~Hz?%Ugoe$|{`#_?`)OZPo3cdnf5D@ZpgK{^9Gf#isSF-Xkw?4GG3(|eF3 za)7P@nF26-Xki{h0h=)^Aa!7%8F_au&1&i^R6qu`%&oia&|!2`nVl+7oznX}9XS~x z0)_7bZNtJw6VgBc5ZA~|7R>G{f*Q%1609B*3P6aGNKoJvq7wIj1ONyYh)f8<65W9# zMsV7$@%3N-j2sYgs+nB@CC|(K;>5^AEKcZDO5jZ17=*DqCvx|a!3Pk9A*qKr4JB}* zZWG7mK@N}*29R1;AJ?I-J^E-KV^eDzt?vDCWz1VB3P-6lT8cnkR98aMK)wMXda1#6%961z zER1C!rJx+KV-k)L$|xE=5DD2pg7yLA$brb(RT2aV|I3d*_iw2~DaM%5HEf`8PO)uq zoVhuW3&~K=XrV!eBXToHpn*AQLNr58xg=pt=sAds;B)|q$Mm_rov=O=uHQ1Xr*!CDHt>$*Vx>A4=0)`_J zKtRbtm_n=tBb$0;3T5Fy4!s!8x42(J3Ee;#Y4R{2z#*1%3?o*|Co7DZY3;OMK_s(T z4|WA&Bgzn>zRFyG8Y8Q}s^j1HdKl|g~onOuP^lXp6 zIKMl;{nh>$b>H`r5Qvl1P^)0JHmSEGBbm{>#26%0&^<*}<66mk8!jMS@pQ`tytVLH z=%lw9TVTHoxj~)|$Nec*i=E(DQ>6)`bjIE{o_La+TJAg5qir2Ue4-=vv?glT6f}?t zv~Po--t28!J9=4a*^YLpJlKRW_LQkTUZ2L}o9m@K&;VLMrN6`Nbc7`~-{R6zV{vp; z$S*&9^+`Sc#ys1xl&76f=;((TX`62=y^IwkAM64&9yKwd19(Xu$1bUlM@w2Mo1uueNaLsP!e|clyYKs5DKI)aAXFW5X_|l zB=B%bAmKQ{I>K;B8vEAssa-Ed*mCiwzV*?aE^Sq*8XDf23oysfNYqr(0l6wVqNm#z zn`=m|**|=J`h)-W|M0_q@rR#(#Fd>uj%dtMo9p`nV68cV244eMC(pT5C*1FD_O6n z+W;fC;oY4zFao0xI?1+9H_M9`hnxG`(`~-JDYc{-ok_^U$W7~jFd#EQQz?|CNSY;g zbjM6V<}=U^XdN9v9hsaE$&m}h0Aojih;U*cK#owr%KyU$KSn2{Kvy;xJyK2~RmK`z zER@L+iBbYdAWSS!h_!UxvwLen45~p4DZ!D2=ag7E5tdoTDpD}9m?MHo4IIQ1;UH)B z=2*F(p&Yr}kUQqL9uonPw*fV`ONd0*z+~OrLy?ENHSflKy>u&E?0r++{ep(>$f+=( zJBo-qp#!DJp-n+7H6tcrBGusRFqDIWHJ50H*oi@$1_67BwFqWH?j}y%J1$dXp~{8? zKtup)%4HZJh>YIyjWM6qlmO(X5ShDqj0X(HidSCguMPdlTIl{--Pp@abz=(EM zpALLla%{Y=*DYW6i2E108ef`Gz1U=!(=w;^ZRiXMX?cNZO9*Lg@Z2Ax43cupQ5>#M zwqw8ao^l)xW#OW`^Q;50KBzsyn>YJaFOT(_%Y5*Jdi>^Tw>CD4R45wc)AHFz53i5M z!gF%U=fIDd-|6(a=#G4a>A-2}&S`zy?TF|1ew_W1TsGWq7~Xoib*LFpPassr_M~4v z+rGNo!^@X-f&-0o6P%81&9eR)>cP2$-!Z(6>4aH4IOFbU7J+Cf6b$wa!k)dn#ERj- z2HKF_9Gue(guxP>5w?_4gqsE1qX$IWZF7$msbWDs|I^q+5$wd4Pw!K7$S6QfN0R7CE&BdP)90L!5@C_ zgMait{f|HR0`RNn@%=?GZN+rmisglr%bhS zohWBab&S$m1IoKReEqXu|Lxy=$;eo8syUQ`Ahw-KWp^|n+n^+YNNOk$!>o7P2PSD- zw@BqCIj6%%uSUC$p}IpPLks{wZz*z%6+ys7nbzJ?B>xsF1+iqxx-1pCT5Or79s&}3 zk2>XnObp3oNpg40cc7s-r38BFP;<)dN~^7+BAP zj0X)MaA~`$vs3Y=gjg5aHx9^$0u+-&I@TEx93%r4$z+HQlASF>1RzqtSY3|bjTwQ& zV8_uRCh6Bm2$aDaL`E23?%`~q#4uLXX&ZJ47?iBpcwT+TC0rb)D#;-dLE%KDyCE{W zTgiEJ0_F)Q&(Q*esSPYy5E>{_W^BX)B;m$HGDe6fA*PhIdA6kH!q`?uLRIiI5m~rH zN!XPT7`=B)Ouh?GOtOo!Iz)hZ1=SHdWJJjsamLSn@73*ZewWu@+gD$$e;?}W<5R?D zT?F@GNvgYVgB^IzPLYN;r8-k6*w6te8QFSxoM90fhh!RM09dk0g5G;%%35#cB5SO6 z-I6~Xr+HBBX?O%8jXV>ioxPp6Y8Ol0L2M-6pSZpQUIG^K4O7J+iy7NH=L3!_yLOrYb7-FEJ(L+0)W~6V%xo2< zLoiYdLV}s>2`QmPTRXJgBSX%>hm;Uyp5Pg{!nb@!1Wb#!M%GC*s77SY1jy!zLlFXi z02zsqvm1yv6hQ!ia9|EJ5^Fud4pJ;AFpvgC2HMq1A{88vQXl~NfE=M~zj^yNf3-es z8G%wp$c12;rnFGeKyWED;l<%d`s6?X0YM=gh|C#PnH)WXIz$dE$u)#9QcxkLfdXv< z@9GpjT8GV{?|o<99@q1ESoa2MfG|SIG29bJ-ysWVA3U6o#%h3kxVfFvAN=tj{_g+z zzx&ZYm|xFOj;B-?)F-{1$2QjY-(26Ud;Ly&{ZTzkmG?3oFdx$_d8Q;REG#DEDHUd5 z63Y}+sSc>~rpsUd&;PLzhYwR{1^~-*j;;jY5JeFeqC0k`k&Xl335s zy9EJ9p69}~Ye&ow0MTMNWeh_qfQGy8;S3^4JI5Tmpn)Mn0BE%v=ydh&?C^X`}_&h-%0Xzfo!I-GLZ4fQsf2&1eA+2xvV;35|b4Be|i+Jk^rS;3S9CZwF0&yQf%Z+(w z48REDNVrIVs-OT51H>V~od*a(C-fMyB1!l_5=LTzAOge*$_(H}z$G&Pa8M{3MPPCV z2z10b@%7xxkpX?d7yvFN5x7)|`IbKUr~hz1nLVHP_t(a)eOa_$`_8Hg$i8mFEFB8K zNaP$Tfb*e>df&&GPE!@QUc1H~DIH+~0QE>TvlnZuti(9yWn8<@eBN8VuQvy=OMPA= z9YY>`oGC+c%MQ`zrYkS=>}u;4hU45f%rb-LfalTQZ|6o`YJN3MvZo;sJ8MF6$`$v^ zdfD2L>*=9w=T?i46Qh465T>B^EpSA2KH zi2}&CMd_Qqewgf?=A8OuxpM)pF9B|A|CR6W+Rq>DV!oW{#gX#NbWWKa4K(WrYVV@n zBBiZQbT#5L)G6>J`iPRz&mI+EMLcLi<{fi&0NN7h zum9a&{OninC1uLw)`)9dR$?kkjRB^;xaV0^BRFP}&SUIRP+ScPro=vIv<8{sI`#OC+GLcu~1bO>xQeAl5pjOy{m<8quIw&!O_Nf13+Fe7-%WxIANqQg;YalOAg-puub zkMD18=EK8buAZiZ-hd%cOf}qX(6=0s$Z$GV1}r4bnD0?9LxQnCtN5R!H6JH4(y|sN5PE>?5JId{J+LyGaUd~50A~iq z=!40T7{SMMaBVp1Hf3&>%$A2h(ZttJ)`MtMO<21HS*Jy@)*dU&29zrD9D0>4J zWFN@lsR*=j*{;a>ut>t&raAya^OX7uyJF83Zy-DRbzJZ^YRq{^dy)+_ioSY9ILf%H zR&uj)v;@SXS z!;9n6mUkC^e?DKZQ^MS2K&kcqv-_LRZ|{~4$GddB=(G?4%&#WybRxDT-hb`qtE*Ti z_OJW=g7g;n-SFFTebczG6V<{u6u$PKzw6)3KF_{92(IP!z#I@0#WSfpWNqv4o2=i! zA#<*p=GZIIBZ>eY39fek05 zQ5Tt~#66Wo2!McN1g8Ll$V|hAZ~_kjQ%7@8(vr_1P$xL`V52w31TD2K@iA7 zSHO(gf<`!!qXVK@_!f>~2%!KAMT3;p6SF~@BNU?pMo?V%)W7(7`}%6#meb7Im!s4K z0#Il`7MkxwcgsrvVvH!l)*=G2JKg|1yWB+bZ($199dHm*5Lp6Naa)l~=r#<7X$)U| z3}g3x-Q#*4tJ$DB`i_vpO*!c1W(*w|BQgt?Isfpxr+@S>{`HUl`RCtzoo;4Iha+>3 z>tjEU>#u(L{I|c}_yNE7lha))tdth1loAOJgn?ASck@6bSAzg_2Xt`cRG7X6h$EzK zzkdG9zxf$CWI;0k3^`2TJoX)6aLz%ly8)p9dW1EXoPaP_3`g2JNK!`tGbacgW*8Da zGL`5`3R(qwvVbdkDhtMnJ%C54GMaiIj9BJb2W`EnGxQDww+|2XVZNQp2cNw-9+%sN zk2PwU*jH(*az$$Z-k}(FPzcE>dlF7r83L0ktjLa0ogAaOVL-y}$V$d+#)w9OVJM;_ zQ`rqBvTjC!g*f<6KK?#Hn3e!f+IbcQA|ng`UDAh=vfD0o426G=0)&a?7B3I66 zl!QSNCdma2)099-BxCcO2!wcmBw)`jUK2LNESN;B0fJj_t~3J3f^Se;2!W&7V91_e zC?g%99e;WRC| zL5$R|`ZTryd*gCn%2?sCx3}l7-Y2~|-hB3On6J0e2*_!%-FQmgF23v4=59>Ib5i-{ z@%@TV8|CB?0W0#utK09setCjZ8D@aRw0@M~iH=L=OVqon?+jvGT(8d&s$S!givMy{ zj`32;zRfRlT_ClP3g7&Kzj)K>R$o&--4-4sHN_WUVtla2E8_+75@b+v$PL;VrE{K@ z74#tZWaS<%t8=Dt3F^7rm>ae*$P9*=fXle{GFCivheHeyef9*gcVEw@=)CZ;P^}e# zgfg0^8B`+>p#fFE2xH=v_yDwnDMC1M^BxTl-&4u}4w2l$S_lni#wdXUfDzd{AT-4i zIspIwJcbKK1Uk{tu>?khFt(5x(GdY6VMu^U0%vLO`|~$%B_R5a4AXQhq|3A*MWo7f z821C@l&w)_)`l#Y3nE}5vW|*SQGzgnsTg1cAteeLfovK>Y~S}0s(szKGd3U1WZmt2 z-J_IY-6Zd$L6+V&9nC0vDop9P@IUzd-~Gv-{mJ)#|NgsoSSxc~*q(ITx5xA2-~8w6 zmz%!)?fj$Py*+Fddn$9zNE%2K;eg-Lhy>w2kYI!Z1Y;NkMyN13B@Yj$?P>js|L5Pe z9s$lkpgVR2woFLsl!d{>Gdh^7W2ACJeE@_zW{EL2Qrp0whjk4>5u_OPFpsrS%}(a~ zrXn3dG#r8Zn3u(eXQn)t7+y-cJgz9I_s-1DQuD;u?XFJu#}_Xj^3B7`Q_;B~N=>nO z%D#h#4=DS2_snGyL6BO6bK*fF;X=ItM_30y@RbO_Ay{b!HZ@qBgP;fIWV5qvBy$Jwh_U_n*Bw$nYZpvgHuEYg{c-t`%AS0n%caRCgm=R+@o>Ec) zoF+)ABz0yL>Nwpq036=F5W+|NOThKSue2bwjL zu7JdQSLOA(uN#@ST@9#q9|I!;hZ+G0Sr0^qnu)|Dk|amcj>H<_Ky}WhM#Yu{5r`3l zHqSUlm?3j$q(BBBc9^CBhi$Kg9RV;9Ms$ZF6wW#%5Fj`LM{pHqa&#Y<0#(rV01X8X z$X?R&s^0(L^W%r7fs)>>V~n`MK8OnV8BjothwnEj_Ent|2&C4xYim@n zNENG`aK43hiP2Y@(7YC`*8A$aV!yeoc|+CyzU`KGfcok<$Bx^;guw^GoNv5euh-`7 zf=_$Wn`t^Y_qKoa_~sg4Jlg#6{qY7L?0Trxn*(v@+5Ae3vBTEMCYFg9_gK%Djnol{ z^Jp}PU%kBl;p_W5k#zKKP%uT37ijV!`PZPg&hKrT@chR7tosY_f%52iiOW&;cY0@0 zUe2c(%LO)vufEtWFY)#U55C9^E!U`b;u}0E(dOCJXHxR?#C$V^kSBvl_AARuEF&Lf z-=(aYkLa$=<D`2OvNW3}}Y2MI<0cWJQ9ODBgi(M{-kVcbFy4P!}>qL2~v0aAgv6Aavr{ zk$`AWWpJvMI4}$}+;_nMKn8@AfebvDKq}(=vi;)A{&=l6a!$(>nYFO62-h-XuJ13X znI?qk2!4WoVME9Tqp>oSg2QkO<;rRi%0Px5I)sI<+X(GO2Gs%g&=KL!_U3uNK5p+j zT*ew28zWnA>!-_}*QBR2h->KE{Y3bm~lA$hwDckqKO1JS?}bjyDhW?&Sw_@dNE?A?%xr zsLk3ggX?HJVIqQ(Fi}vRMRw$ju#+Ut95exS{v? zA?$|=6;m>m1tb%s#F=S4W0@$F1j86vgTW$6x`v++t`xQC{SR$u4u{MUb24u*P(t2w?s|MYrkxLve&=rndN5(aKPI8U>100S~tChuxe zc@l!2fl|SW!ru20PKBc3~J&iTrH)6Yb@oH`9DKFC4TIGvGW^oS6lBTOW15 z=vt2XF3m;rzFp4n{ymJFWqvt79ORyZLu@;1z9W5#^E>c)v~^RYT8qBJ{TlDjmuCUy zNN7*PQ05!8hvVnXWa)b%&X+;q#N@Yq(hQvmU+M z_X<%yT_aEOv%lM)z~Po&KF9s*nHQByc{a$`up9I47e)OgEccNYxgH`tCq8i6k*Yb< z<*nyeDFx8cw{MaMkOSXzDCyF2U7_3#MFJyo($3_LqMN1nzw|V0u%;6iDrrm0iBO6@ zyD&ml7%ALsV3;a$G~~>vh=Bw+cDLOJAq6r!3L-fc=tTBqk<@&a*qOu- z&>5^bO~93~12Ym3<(weG2@yfuhGL}%lx#-C5FrE+fQg;SN0jR?ej4W?bDBY?iLe$x zAhYV5*8}O5jtf*lb{RV)2}6bk841ALMF6RK2$BUB-#en%-lI;Vg(K?r-VCj`%h%VA ze!lL{7q?-S_yX0ft20+}D^yCIr%yk;`ThUupZ)fK|A(J{;I|8Lxn+2?c4=pQ`t{$v z`}426y{y0aJ2xLJ2T`WNizISHaMOSYG{p#q0PrBU2vtO;7>)q|=pLpdfW$$e+SXCt z{rUgrmtSt8350ap!9!Spf(Zywil^mPVU@~tnPb%mAd`KEF%&AxVL}b>!*!D>7xc7D z?%-V1m9VgPW6Q*j!hkQZ|LrI_=but2>3}X!|K_mPC1Q6z=!RVUFhdVQ?52rlG zI72!B2cn}h3Aq~otMB|40x_cZPFXUG=MsIS(ZDz&3OMQ@DDIJCA5=pf4MvtU+>x<6 zPa?zTJg1q5BIO{8goVhN+?k1hg%JlcF&Dr92&M|Y0U`C`=%|Uw$(rS(AUSrnJ=~zN zqtduIa5(qvIs&b0BL+*YX*cJ?fS zY==`qh4tK(2q&%mdq2E=_(#7X`qgNLy|use=4yMaS9{)RG{xW^F%r#47#%3oi9nV)!%QWAnJ9wO6m+27NcxHp{Lt{(l zZM)c&ib^6Sv|IDeG+8PX}Y)?tPB+0z;O!uIukxRq-Oc~(B? z8S+f@y_ca^{NiW$yl-zd$mlN~s>NL2$KfR#4R~bFRyxGNRPpja8 zN6ym#A=^VZAcirFM*a-x5N?bOk&#kZw-Aik;Q~?s1u&QzVK+}6_sq|Rlam1E(444o z$`C~8l4UrCs?-FG5t(QpCPGw0;Rr{F2x4aNh{Om02nZ~WhUO&bU_KxFoAvqEUrLBj zr1@0xNHTFrj2?n;GXbE)PJLKL5{&-az@p#oM!QQ-sGNKZhv!ygI^5gG)=MVq&|M2}k`uNjREb~OAGQ8Wbv_1X$ z`KNCme|g!`$J39$cl$uKB$*GX1Y5Xw93BDg5b9v=X2BT|1A&EM7>;Ib3nYY$EQ}o_ z5s>L+?DqKQfBP5z`N>&PeW3)QC1>y+3^~o(I;>}e46S<~-Mvh+jfN8gIsy=i^)pMd zaAuF)9kgH9<``z3Lx(X*S*BQrgC#JoN5YX9nHeJ?81NDiG!wL#32vwP=Hc|>j_)2$ z8RT>XbS3n_5fQ_P3Dr4Sk191);#^q3JFo_bXMG+t(O7bajLNF^If z#Q+(5U20cDP9Qx4U?l1aQ?afI$QS@4A!ciXfqN&!lpGKk!vioQNkSKh&SaF29%GL1 zB#L2@sTS;j+N5<6F$gK~y+3?;{O(KGEM4D?%euxAUwyScZm`;V)G zzqZR3J_}4WTU>jy>F&k%AMQUn%*U4*S2$+8zW4hK=_7_;ITjS}D)jDcU)UcDq>Hah ziD)!jKFPS+2e0__ooYXgug~inv1yL!6(49WS34Zix=4J{^TO?@`oue#zX7=S>=MU` ze#JL;k*ZvGrJa!t#f0cFWB-Ng9HLPU(1C2FoQQbDEnP00e(ux9tq*BuyPWN-U8iF@ zzDx&9B^6c_c1qkF=>l{#CH5Y;B2|wR`-Zp^WVgbun8+XnpvML_F|_~_7so<@$YcWH zM~Nq%7D6=fzyr`8QUDVm1b|~nJb(a*$&Gk03fc~~BX@8nJ%fj%P?!V6HjsKiCcBbI zBuIH^eH~x@{r>jpAikW+48}s3DPcx5j3gyNAR(ZdyAZ9xKtW_2wi8zzD?ljU2Cdk@ z0H6;)@14-s)l}P62ihJo7~j8NFU<$#%|=UNP9t%uhr7G<2fz8l|KflA*WdfS5!?b2 z42w|Y!nQ>U>fj>bhGr%}ib$*CLB@`0MV=*`|Kx+;h~Wi?Qo*^x=*Y}DC!x`u5hxhK zC1tNUkV*G=6Up@bl!1{XW&#Rjo zdT>SWtxhxe@Lf>^(GeLMz+q;QNM=3oSaR3?_0yZ@j`K9#zV5w9M0__f=+gTn@rYzPBCp>9TdZ?jXgE z_cC!z=gW2D<{W}k;d)-L9fFq^KmLvTTe?Yz%h};I!;{xnWxTiB6ZR?MO*}T(&qEiw zJo_=xnt&fWRrV@(7rOcWT!vl#X8#fgCi>t9xm@JsLDmFzPHHMX_7l;&ksR@6^b6rD z;3qoXKt0f=iQh-L>$E_7;v}4aiM;T>-DY?P@-nUOphUML!F!$(6yCh>*NyF`5KDV+ zb{TqF%H4gQIp@US0W7FM*@9Ue;}O#0kZ^ax?joubopApez=D|&K!8IWnA09sF~ZOV z#Swy#L^`-Z$*5>fk|2OEh#6B3^9aC1;DqED9RNr-ZR$>@7@iEsor8fGE!cGc5dg4n zX2@<(k)mT-`n&7X&wrIrlcZ@9WMZl@5$D;_89J&VQD9?LKw{6H3SdVk#1YO&j?u!+ zx&Z-pte2w_iQJZGN$_yR=X#OUm_oA56dh5C7qh{^Y;@;g1e4 zXRe1+qD$YleS_;4KfnI%FV5HF{P~Z|$1jhI&4-(*45Glm2saOO^@vb6cLYHMgy57w zH`_Nw=-Mx?*p1Dx4ia){#q zmKM_~N2!>^dc#0O3UTd9E`+YkqX7zx5#q`%D{U0*}wt>txwwfV^Ckwam#KJ^` z!9a*H8b%7Rg3y7`019N12ui>hBY0lWc$%iAN4cx533U)7B!V0?I1T5_V`G*W9bAKN z5H1!3L?Zsf`oR873Z851Pl%jH^QQf3p|*qfu?%qEH}CEpDcHQp1lbZN z3^2~ZM9gGF$%1kvbjs{d)pj5uBD8^oEEpXWF$>0S!IV|47Lw%Q;u;3ULXikOO2HVB zg#wi*i@~s@qopdldS6KdDA~R`_<+RcvmyB&40`iGul~s&=EZ4$8e4K&+t01tebBzT zKEKy>w>?s-Zt9$}j^V1BD(N<7LZCDy*hlJZ$2(6wZSC!2f7`LoOhFE%h7kWtySnsMc8IX}vt#MLE)x z9`2W;m*+8dy`144iR3|N+^(_HAxkwq;R@(BEokLl?;X-(tgqE(2Df8R2k{Gt*&35 z4J4LX=G&S^nSvxU42z60)T_Y7B@L}Kg5+#+Qc4UV+#Rz!44AnQ;8WxUy`VJYATwuh zLm>)rgiPOphH@fwCkU8{o+!;8slXb}U>)p=ZABltUEFPqP?doU0hEP>f`T}KHIfQp z1Ox=`5+05jkiY;vIN3Iq{p)u$#&Q5kDWMCBQAc7bjAWDuVIXBdXFx`eVGK6h!v)ci zM^Li#g8E9T(YGkCY&*lYog29L`OW3L@z>wHdwSF>(@rvoDVI9uAAR@X_y5^H|Ixqr z-OoQco=&+eNcyag*Y@ts_2>Wj@fX{wC;9ZZ?!I%HC(QF)*g-vDK!^j8tGb5~1V*3( zMg;5Cp$=CcVh*4oxiBM1WkLi*aArVuB^o=v`Rl*@U;pQy@8&QD1%pEd@S0G-a!O2~ zJrRz8p&bD!XNADA?N_5fP)9@&WCACqocg*^DnpH{H1#9}ZG{AVi{ODhnYmRAWFv&Y zz9|Em0YE=Z$NLWsuO5ysULFq%9VVfvNVk9pMhgT$MeLZcc!7~PL2{v0QbFk802l~> z0B8w;ED*Xw$)?QMfxsie9J#{)!V2IBhEsERLGhL_6Ba}buKaJl^EtX<7U&}{qLx!- zBsOvmM>-xV3|Y%_l`m zg`q;(wIer5oIO)mLtpo;kDhN>C_z{s@y&MOL#L(QzPMS|qX8ROY8Yay)UW*ZGCFie zoafUmXWE!(*SL-&=%p_;Kesj_WTICOFFvm?ULI$d#NTQn8k5ZLVV+|@Kz`h}RQ9h2 z9%yZzH7*3L4abTIHvqREOg?n~BEA?y(|GaG;gJ2dvZWMX4f$@?uQds(1ZjdzowXl? zoNtBlO@a$~ivxSy*xF_LCMtHk8T}B~FL@Ed8FT{L@GzyBhaqnca(2Aqz2W|AZ@ta0 zVCH%{q%;C53`KbiJW|jAWn{M?bd&@`pc%n?N)lYqnb<*;(y2rEfQ&mN3eSNUU;#p5 zVL@;PK(a)!f(T||U`hpj}Kc34~6cRXMAN5p+_2azlvzdZirC%^qW|KflDTYvP~$FI`q zaLDik+qrM;`gnc(#jl^g5x;pkfA+(>k894nEJdh64Df(&#Rv~4Af)gJ0}G9|+U40H zQzq|jKtwI4iBl3JLn$HZ+WIFiY}fA)7>4y2En^Wm})~e z?SWI74y+FkH!mJ;?;cL~r*xPUYzjiQ=Dl@bH}c@ zn9%|?bV|(Kp`vLwAa(*~L?9U5G9^4vQ%6dM`wLG?E;TG-qyC-+LSRaW^;~PDiiYattsToHX4`Y1?+(W4SsTvcGzL zgf-bn2p-eEKU+QE_9o6Y2z}RiDGwjU-A8w2p-2KYA@-OSwkqj7vhd@@%={u~Z~Eb* zvTB!Y@Lhrwcae^tmiYPhw)q!ZzrRoSpG@@;$|3hlW8(ct^^2yjOZ$4u7}t|;S451P z8yF-7IEi<%@mw{m>^_RFC~f2A*~$s8htz&WyhlFbAi6wyS)<%}1U#FqU$uAO@4unj zhxD+dnlf&{NI*T1u7JEEABfZdf*j?*&^$?Rn>S9rLk^4rI8p?N0i__sR@r~8^$sC` zh#*fCd*Cbt z1dP#*6C#)s5d$)gjhL7c1&MePr*Hk~*!Ho>yi;lJ-#kGVxVbs~#t%OIt$+GYe)P|N z|MMTecy(8n3}k!TwOudkH{V>}jcqUK;j`tFPj2sNs!3{Qaz8f;U?Eu5(_Cv2 z!vxWoF;NX`)?Lc1?;bsYDua8tW1gZ74?-GJvavu=N9B6pEL>9z$fz!GsD}|Fi~6P^ zsb9~kv2J5TAoElb626{Kr@Q&p{qo|TPKS&+^BkznsW&V*LYZI-s6=Im%q)q`FzqR3 z@PU>QExe&{3^O+ZLhb|@juwP$ZYDS&3WEY_xDqp9MNtgXsKLQr00+47|K+>CNk~Y; zoj?saGKC^WWf+5FC+Lw->84Dw{;-MQd)4XK9BHK8lQnIOD}BlrmG8;!KP>OS@;_IwWT z05V~0k=-$z%_+^C0x$~7K=P^Nglt2W?A>eSK3qnR1QFT5y?LH8j%}ps9$?Dz>|lw= z9iy9CAUTU9f$$a>C5g2i5*7CW1VnSe?q0|dv5Tn#?z=fthHwl>mA>))P@^x zc+7+`O{Wj;miCrBX@=hNetC}3{qbpkwns;oVAZ!+t~Y z)y6N=dNxtOS8!-~DzRj^UZiG2i}j#>PC9I!BbATc{rIw+=`=?TqCJbx!lnhdV*{j_G;^xL7(3#DW2MWy}BqmW8hv5Md?;mMn7Wd)PJj zWF8WRvXUGDhK^H;CrnJBfF_taI(ZwISRZ}Q0FRu}A^iOHc=}bl%!auWy*4`uKyTwoW+vv;x`1Akm z|NeI!ghPWcVG7sKAhTeOR1$-Dq`OH>BS08IWQ6CE(AFXc#6d=5G*=xG(9G1*lCgIj z`*bKA+{P0lkKsU(2)A7uih0Bs9p!F0G1~o6UcJ7(`{?fOu#~C@#@(DH)(v(7GBh5+L#xG8knj8e% z)j(PgYwqE0)UBHfl%&^H5@X6zh?v|u$&B2c6D&pg#uzbx1Caw+i3EfaQ!ha3C3D{f zDhBrDIJ=Sx(7Jodh-M-Sqcgg7MnOPs8b*SaFzuCsPe8`a6Akj>0D?g101O_eGzI{s zdFmhjx|uXKF}Ya7JSS1@4X!HyYi47)hgTO1zdnblKbG=0A_ zpXR&!G}XgIu1GT{vXmh9Xq}0f7w5#w`ZzAujr%BG4|IdazDZYie%=D^ zr>R=;yo2lwBRY57oawN_b!7J+&n zRk4lbR(-AMjGgQ+KkdU{L@^$61>dpP=H++30 ze2YtIDKgS%&V|5XsHLDtFY@7!4-a!qz0{f# zVRcmUuz=sDPtl`h{FqLC$%;VD$3X%J7-{Wg3xX`C}N;+00cTT0z?$X zz6WzDscB4H!;P63Z~zVMySsMp?gl&sqv@+xHxIX`S0A1p?hi|KLWq=6_ZXYY5xoyS zkaa0{Nmfh`aWAaF30>K+gspjdcd$4H(9q~d5%7U*Zx8gKw)@`I4^2Y!AvmXWo%xMg-(hQR$;4mRX*Hi?jTWk&fzYO8&&uv?FALji=Gv{1u z?Y-ajbhmDGB#WddQGyIAmI6dEV%YwgAW$SDM*h2e3)0vI^2IPL$Fgj}QUY6&Em9f*~PB!J$6on4^p2d@#|>^;13+ir{>p z+zBo*fJIf!PV76|?r>r!dPC_+`G(>p>_Czw4T=)9We*!Ku^CJ0X6)^dr5RZj9*JP^3~eI~P-c=a5*R3}K^iNzSRoWlT@R1-$N$lvq`CO( zUr{Y1r}k&Rtglo5_{^o8ziCpY%j-E(HnXvh5EaQBpgJN=$(!wCZ&L0LH>KY&O@L0! z;{_YUHp@#|eC*x!tyddu*s^eGsgH5Z-@mqXb5F`QI*)bPo3f3*^w4tT)6^1k@L{+b zJM-}8>d(8k+Ur10(!Pt8w$JwZ{dof8zD>L!?eBAxb7rA78`q%rX=eo~$_)rcPoZd{d`9b_j5}$E9yT76O(sbr^ zb>2DM$@~<{7mKZ9F8uXxhQ0*`?8xys3HSLe*Ubheyx5ePml{)kj-;RBH0^kc^Un3_ zpmhEIxzmjtPRq0(r|O4;^8znK>%hctv#hnz_@4A85_@OzPlN~(kES$x8Y0R(z%afQ zyAXBYU}j9JvV$hLjOK}KOeYxws!ZmNXpJxD>q}jK{<+cQ(~qY2w|PQlI1xiggra%e zv9FYKkcDy38eW3KO@+b-2Rel~5hw!|gB)ywnE+!8f)cqKtC$IEo@qI9J-tI)()m|B zD#@f|K^B9Vg~sNZI5;{Y5qr2KvdY%Y3Prg1*lI@`L;Jq%Te^q$m+#v4ba}mAzmLJU(J#i!^x>z6dn#Gdl$n&g)35PMsX#FtaQGVkp?d2~Kc9j?9`8BQb-)AR&YbLo=ZV*?{k>eEU!T#XtL>zb}Ur zUPbd%GK<=}ITH<27>qf%Bz7}LV^9y#oU%ov9863>91s<#d5|Mmm*d>rCFyb2zV0Yc zh8|Pf$G*q5TTp5Mr#vY>ynXZTcDZ|h_vPDZ$&zSjDzIS|gXb6#7{kFdREf(Q)+%z) zVUY)DX4{++1>8IMHkf3b5hFCim3@#Xg2^@nK!&{$i3pGbHiuDQS>#L)Tm!l0%(UtjV0b9;H+dODO@Pj8P8KYYB=7rH&Boh)ybP9(*8m;E{l z#fs6{Y@!77uvO9=^5qR3ell-=cK!bI`R5h&Fx^l3K}gD#JCJ z-T&r?|J&dD(NFK*+)a7zv_03$SYN-te7o850n)LrF7Kx=-_A3#9MUYpARq2~xJFbO zZlnN{)v)GXMht^FMBKe^!38v!Sb_q=Nts-kNt{%JgxM*S7)%Z!_&VU1EB^E!{}2D_ z=Vt~anwqJ?xodKekPv~`2omUResg<%;)LCa0AWC$zY}Z_yZ0EdfRw2l^f;pkP2+p~waIE6=u!OoH&$X zqEHH`YnH4W95TPBxR4MlLj+bxBcwt>RznjAS}I{-H|)EB*ax)16}FRC?PMm@YNOI* z($+ER#j=gfTknI%W>qR1lSYJ)I)Uw!(`pWKBW49WDWOJY#M)hi-H^3Y8379KZCIqF zU?J{E`gG`+mNYvGi+-)lwO;qFl6k8;9ynM z(7P73c>Qq!q3?ZxF%!iwNvW;As zm1UJ)huLb`3mwF5d-hM~kFQ?mDc=>o8~XK1&;IgUtCIfU2Y1s}BGi_>@36!NP1b+_tv)x_Rrvk4MctFFdaOa*kJIa$nxQxqo|l`;g1xuq<(<^oR<&T}kfy zx!datef(?_S*WV`<;6+;nCb9X?uU-^<>#;4%cA+9Z$m%)?y{fh9=_ibzV72jjV*0n zPvk4**M9g3kz1LQ*_bN(O)J?}CI1HWL-Fqf;YF<;xc!<=$@q>@ymqA}(v|Fl=~7>A z^5xIR`gvO)<@SC)Ug&U}?6arY`tZ8Jcj5`k9)M{S8u@4=e4{k2p$CfYx`-R=IU)}X zQgs*V;Pt|Xg}8g3h$GB_MmB_3E)QnTyc1`5wZ5Ta|M>0tky2jtewh}X3&Dppb0z{a z!(0N1*@*+m0ghn-VipP{5<+vy3=!Ww!o%IR(UmAg5Gx!;mf#L<7$7a-N-ShUl>{-S zH}vw9`ZY8NnUjYcTn7h}bpi$*8C!tERu?AswpAyx-p#qXv_6lK_}!a#fBgH8|Ng)C z#m|lpZ*J$iBahY2FYWqyyX@PV_;{Q6+0MHxKhd{`!(2E|W$I+Z9SjdAiWV-8h_(;6 zpaP!A+{4&Fa1RhC0XS!t;Q>)){FV$>1__feK#7XeO|q_W)KcyFf2F*zD*0XQ7IS3l0=0~oZy(fhWcC~Tm1 zFo(rxt@d#1jdX@gi@u%8mp^#-_QU<%jAc=s-*CDH6^bzk?i$E};H+}E$-Hq2b_FIE z5vrjU4kC70fNP8(jgVu^Gio2)kqWuNCr%?kM6=7_a2w)YLo!H(0>aqDO9@-O+=Q|G zgP;EO2sQ$-haa6KeCR>OX2?V=XT{DN}Gx<(RWo zq#}};8_h=oL7iNJnUu*Ws6d3G^I(r5kib9;_GD#3TPfZ1xDd$AoEf$|i;rUGYnK?q zM+ZjpfU~rQ2#Yy~8|i{!8p#6cJ_M?h!zh@#$E40+c9^J9SZD79@^H_Y``$bIRE#-f z#MyLKvj9_oBnBwNbR^cPbS*G5=HLYM5H*Yf7~C;C4>36NPP1)2;()UK?%(^#;jjG> z)hCie>|fP3c8}LTyIf<^v6~h?ajVfFqG`KUqa=w(wQR1_ayasFuP7n;hGZMtICsEV z3r~ym=k5H|U#iCGaCrZ=?63Snl@Cu_1uyw=dT=|$h2yrNYr;6)3HCI24M#xMff{fiml`F|_ zr637+$BYrgnF__|gn+0u_g{UrfB(6E{St2<^W#BozChO0o+xZ&#mLS{1{g`k9HdUSJkV{U*O1Tn&#e6S2od2Ga=f0;-n zXH#Vc1%XD8f(A^Yov>pf;StIxz>D zNFgB#_Xt%bEdYZDlY}G%{gzWO0t_LB47c6V^69H@{>lICzxmCEDW&92pu{B`VG%-( zVUmcDL?tKNdt#vOH3^i+R;=T3mGFnT5UIEEsdYW1rrKrFt*i=2*h|;${Y^+Y4 z^UU-(l`ntv#rrqQ?QNNl^IR-TMNHgmq?xTpA7Q&`PNlK$DWy;+jg+d50SDzkw@#!z z$Q-wLI0S4% zI|maD4`wGuDs2yTz%#>5x$VT@Dfw#)uE;mg$t_YxnKD`AC1vHJ&Qsws!B^o-*onjv zi%v-^5kYc9Cnk!91WJcUMyMfhJ;=C%64i}hD6lSYb0F$~?>&<5JtzzV!}cAmkFAH0 zA%uD6eI0ouDVzr&c|bKJg3Y6(l6Z1QNT&!lEC&rEQ6_>%xW%lwkI`&&mIK8I=>x+| zxNUu!lUnC8iFIm~M&sa+u$U}turfR-MVidRn>ljbThuys;ZytZ-@99W`XlY%T7T-_ z7++fZ%dgj(dY8Hy9W*zo%^VqRIHkjp6hyVf@^IumRciyrAosMdsuk&W(P~xgecr7i@Qnm{_vxjKJ`oM)i&WW-N?i_ zHX12ff39AKrb+Yh;q4C}9}aa+q=y`I1Cfx;`;q0v@&j*VW(emoR@}v@1%zk z+sFFr%k|sc#;LraeDk>QH5QTWB=X&sA9Z7tC---gUi%_65+?NYkoIpiT{mM2-FMBG zSJ#$+syXU0x95?R^Fy>LjgNXvq$eNZ?PIKN+t=%F)KBk{w&mXQ>4ZE4#r(6; zL+Weuk#UMXC@~aF8Q480sXH=9OvRsL5nutX?uDCiJUJf_BPwI;gR*i8RSH)CqM$j% z)SZ-}EZ58a^y%{Fzo@UyZ+>)mT=MCd77bbrhmeBqEDBQi;FN+=nA31l_7M^n(}hH( zZO(NRp6a+3b)c?v4tN3&#JFdyT`euB9L9?I{;YbDpy?1r0;&jui0lK|u($KE?n*qO)jFABG;m5deuwW(J6& zchU?>Bn)K`vnFMCV)pPL6$TtEpcdQ*O&|Z_tN;E#|M?}1iKH1%b8we~F$&0hbSEYy z8+(%CJZN-QB^qe%)y#&l327f)bJ>-tcjkmFu~#*O4uTBHC- zCKc+iVayZ((nw~IG6pt7GR9y^VT0OL=H!8raA1p^W;e|l)2Z0mmPck|F;V5-DS9BK z)=0!`Kr)9&I8hGkM2Sac+an`{KvT3mLc-KJ`{=QTbJ%r++W^q$c}T0BOL$9RBlAF( zDJW4I64FeM+NroVok~)6BhKX0GANQNk8rfX$K>0ti_&0Wzqaa;PAU*;jWbyrl*EZ6 zu^Nr;#>S*0JS7oU-qvwirY?ek;e(01!QHwUB{Fihl>7%jdw=-yZFJ!Lyw}V6^Xui8 zo7`&ON1RSmTd$Rz+=J`rdDc0cp}HJdht%G(^32?ZpWF7*!ZF=TGF)H#cB!Mx`840< zUXakZQ_8ldbSgNLnR^}sG!&4U!P(L)TAnwszh&o%D8^m(J0AAKmp@#VMeg zioSbOj(0hgBBSxaalD5M?`Pz&=H8pNA-hw&M7obQcGtqtA03GE_N$L;gQfYf91ruB z4j%r#U>lRuo^?ET&1yn(H+)chtfvRkW$fSf*CSmn**`^|OqLib=e6^z)`Pjx3|G_Tw=VwwC5xbh3=;`=R||J5}yV;YG(R0%6&4Ju2OD>8?{%` z5p0y^fx{GoWOqBtxJE+Q93WEhjvx+Zri@-S0SQDJosgN75k{ObD!9_X{`vFu=byVw z@^CoZCz+gPVs2_XLz#K#6fDZaQbF5-gUyjByjm1kRRIv_8ngvUgtHCNLe_{fU`7)d z42fuv1XK8hP`NJx!By@k>qTU$Y*-ojoE6)h>&UPK<%(z65W@`;Hdg z3sRzYzmxvt?@fPj_xLzX$6RhW#~J7Ietlg({$_veZT`KqG=BY!eGEJO-gM7QDIX3= zjKCc35r`D%WE3pu5p53_$ZrvOz^b{KX)uREg_tO4zzLEl5r~nTU;VRx_K*MDzijRZcrYo-oNbRoDKt%F8@sRzf}jz7z(l-LHE2d=vtHN1 z24it%3}a#j64c1tZPs~sjJiAY@>)l<8Mg_pq|20k_;7mr`0(Zj_outOEHb5pTqKAP z5zR;RHWK`_!;?@=Eda<5*8wFBnOffW>LVMS>S1A ze+AugAm-vVykCQ6)U|=JZXM{&JJ8lKhV3<&Fc?JvnbA$A+?bU^nS?>sJ!Lazv|Kw; zZ!tKO-KkYg1z|%vF%y-j``{o^rD3CcnR+8J@@byNs*+75Wox^c2%##L#JeNeh!Q(b zlXbXv8{Q(!W%NJ`=Q7>d7k~fnPY)B;@7gEE%jcJmaF_nn^I?(Fwyo@w#~&pY!;ZXb_}`qcbd9>qrF;KbT%-O+bKk;5^u zjE<5?b&BD0^qt$@tFKpoG1PfVr<)^Q@YKjl>vhC3S{1jnoaQ&Ti}Xpm&QrB1_a`~d zjy*cl)47Mo1tT@(9I-^|eE%+;ZY)>()o=Fie$}s0<~KK|R3_(`BnZdq<&HOY{yf@y z;m>_}OlykctMzvof7Q!_d^*4*ge!9PPL=l)<(CMej(8coJ%v;`+=gUx zfp31D<@Fndo|2qBg z59a$=?%t%EiLvT-t=D#W`E@<76<_G%2a&7){8u}F=^uWicO|8i4=F2iv*^Kw_)q z7ytNw_?Lfrj*y}(qa%h?*C}`3Y~2Y2HVO>45j$a~19=-u%3Q=+4dRlfAjG5w%bM#} zlaR@hWq)VI}rP zB9kWdobrLUlnQHBO*9WyCRd-1@ZjP!RWd+@B`_EWNq3BE$WHSk*G)Nrce3nxBfO=u zaSPgBJtSH)NnH1Bcvx%_zKyzD8{T?%mtKVT5H(>V%AJh8QaYwttoxJ+q`Z61y7EnI zXC5p7E8)P@B88Dm(8eCnN%k5!PeAWofPjW{uH>9zbc6s((?J!m?ncbP;s%bW0fS}{ zGh|Sr-fLu5`to<=2mispllX;Rw@$qN>tABwx((2TiO2WbkW#4I?lxHFUhzr?5K?%lm`DKcy0#;jRo zgoiCRuuEI*eBq6l4mWAiR4-J+Ms5U<^m0r4Wxjcwf9K8PVJjBYI<&ZE?+eBYc!qj? zY3MeRsXxFkF(=OVa>rht?9ZQ`zuDKl%(oBomx<^5qJ~2m`<`B2LDwOZj-$_O=wp^| z+v%O|Zv5;Ym(;)V`TczPG!ALBBRzkn-Dx3B)t4XgxY7PAy*(sdLW$zk$B=c8wD+d| z)ump$>!gqO(>y1976vI`sdvT|YQLd*igIHnY4s>(=8WA$%?|B4=8J>Bhk%f*J0WTl zU4!u}*8^oiBG&?9LO^p^2n~@SCXTatrgrTw*X^rc?Jv9Ef04g@X@Kukysb4L#*X~;NhqFF6--`j~B0xzgOO-Cev~R(Bg6q%t$plzfa4a-7nXZ8Z{zX5#LfC&^x@p07+f*z2{2rqP>&7PS2cH*1I!`t`A$A^d8dp=~ALr&a`1l`C7Doja4;T|H1SPug4 zl4Y1i7$C#}nK>*BRBj9$!a*~W6C@JD7_c58EJUj?g(Yt!h{y$#u??d{cJXw;=u!s? z5a`lli2TDJ|310tq=1dpq7ZF6#4$jbh@4;dm=+r*6S;-+t&f$A#&E{Kl(Du6Bc&;$ zs*$Q@Etn`dAPbc#11%ku2g7Aj&`Ed$Gf|IH;GH9J?UXrOhzSZH0c%(ayBHCT0iG-d z%rMwNwWIf_hM`*P@a`d@5sgS1pg|(4%517)Ey5Y-%F>GRUgNHi>0l!3AZQ71Ho#M@ z7Q#ZtEJOnyBeQ^G^pGS54dbF}G`efb*4#WwX2^h)KB}uz@NiM-GWF|qgal0~)gS%j z=HYMujB$bQeXq}7U+Hy7B9>^M&r~urXs@r0IICC%rnCs}t%2qxjnQJ)>*)Eo2uE7m zc}HVi?hn&k^m%=L0TJn87Ban@pReWhV;_g(;VzduojSEj7Y^+!l2Tvkx{YhQHfoZ} z9Zx4+TC=^^Q0J+6FXY~NdN|zt@a`dbVhmppgVoZ3LnPKp?7W#ZcS+*a=EQc$Gwh3d zseSzAcQ17x`QiBfX1YI4yQcY*&5vBe+{fl#nU}R6?y}9}SUG;6{%70tLB2cJwEOxX z^37-uslCv>j&)%ZzV4cWA2_B*_ng+RV(v`ZlE_BhUg>%7&wHae66G)MmswD%*4f7z z0S>q#^fq2MwHG?Fq|#7Qb%~FW9;JbjF>{{|zGXRoOBi&z^;9C@wt345A6>HWtm2Y| zgaj>Ic>4q)i9RZ#eXh@aeEnS$;y1VR!y&VZS6#Bmg8popI0h^Ex<^v$h;gO}k`$vw zGn0ivz?s4TcT9paCF0Joh;~J&^-H2Qpa>$kD-#7d0Jol$zeh)?_#jxNVZ)uhA~eLH zWSh2+XMOrcluQJ}LIe;{iE#7ctn~21_IrOL|L&J`&vJS%w}tCDUSHd~ZZE&A{if5s zKKvl#`}pb?TmMl!ye-GbbIxU9suG0Z@Q4m4ferE+p|CcFf{48n6bND_MC3`BD3rtl z%#1J!2ADuZ0SyNUK~#E-2qY3`2$2&M4)9=daF3wZXZs)jpa1nQ&dS!gl&Q=-+5G+< zTLm!+Xn<`uAg3I@Pg9}+cxaMZTQj7Rtqlt!ko7)b%F4nbgPF3ZfrOP6X3RMkxad4d zzq`3VEyugZ`QiR>I^Q5dE(Kz z8B+v>q7Iu_FATNrNmU$>PF5T&+(C&zK7cp~*5HW=uwl~_;Y?HPD%s^9{k1DtK1`)#j=jk-WpdM$GL$=&DKe=R<2iUG zrX(|^N?>vjO~fmkk`PHI?!+8oGD`072b9xIVLi~;opee()?Ma_v|w6tUvZjHtJ5ehCXm(;Y~>K{-Ml0YCzJ#Ng=uSSs`-ACL>M*pX zH84Fa7TzxHwU$dy`c96wx5v^;vtg4Pgfpjf-de4(_wu}Tq>|qr4&ImAoN^bYC=heA zb;$hY?c*1Z$LSIS-miSR2L`C? z=*{W2%v9U$B9^-UHf26oJFS#n+ zZ+&?$gMrBH6FutCcjM~1z4j@mdahRd({(%#^hS?|Qr?v1)#oI2a(=em=o;=TaRJx8 zoUkrsy+}SwzUjtvov?lMQe~V_R%ZdyxYV*;d>+g<9!}6;jD8?r?35Y@FP`idV?}OXtK&JKFozy>dpD+k{;UF8)sSpM7 z1Q-y?@N^hglk>-r1U6totTs~AkrG*Cw;p9CbFvBwP#M=N(i+pew5!WY0mRaNt`8C3b^m#;UN*`tvSR-jSv?lxO4I-5_>T7a0oy|AdWpE zvjjVl?*tI1pa?LF6Nym3B3Knc%t$kFXv!cE1&4wA;OX-({^Gy?&wlar@(Mx{wSW@U z*PY2V6>pLo$V7)(px|IKWU$Uc zU=2gH;h`k$Kv850|7IPMc}s7DmpZ-n9g=unX%L<|$$rBjMUctrki% z<64O+m>5GT4>n@tAY|jgMWctXxcGY@A)-1bu&4NO(&$yTiP$z9MO~TvfMu8yk4>%sR)~O^`$*C9}cItj|WUC zK0+t4*8q9E75dK7BfId8`Qb!y3nT z{T#kub^WM!Y2Xy=kot>(iT3mLb9LKrx9GzgI<=s?bb0A`jrun1+~*sXd+bkyU@hZ# z@;#)H#BY2qE!_?)>Gh>A0eK_K$;Xv@t~{sL7R!b5Eu{%GSk0Gv<`*9`tsnjRJS^;7 z`!`QxOWqd~qd|0tX%b#0or^GgVe3zZV|;${(c&CEo#3To1|4zWpd3j&1i?HYvSK>0 z3o#>*qQR-}6Wc3fVr6p?j36C#5XbPLkTAeIg%2mUi;#`MOews%ksCN`0OW%yNQU`I z&o8*F+yXa*O|86fQM~^H|HI#vAKa8Q%2CVV81-p<`re*DT0_W*kB{^HLYHU%_!{)3 zfA~TsDrHJX)nK89PHw|p13~a`?+wmDApvF)3J6!@1aBl92=F9Sg(N7c7={NNL6j0p zSPKy|Q?`!OVw50u6&7YCKmrhUSZCspy^Z|sKmQ;9i~sVk=y-4m^&sU0xR3zaI*S_j zoYXsd8(K&x(N-Z4La**b9%DGEgyxWW0;29+#6Xh5Myugqp#f5z4ol92!k$$QH>dmC z`Sxx)-W_I&tZq@M12Kj(yM_~dK#EMFQ$gKhP6{GU?gJyy7{su#N4_C4loX>y0(la4 z50Ox7J18>^paf}=rpVA~w(FRV(l$xj2h@WTM74OG1XETD69GJA29gl5WR9dftI@2nDR-m9 z+9PFQpk(ol;Z70VSr43N9)seRWOs$TF!mS;y^VTtl-M^LXwjE)$b?1duqlu)+i)Vyr8Bf&>Zi@Q57TmEiC+7#ZB%>DDrn z7ADXzW+9g@Q}imBt3V>Ea}WvBs8k0e+)W+v@P+>PKm7Odp?dQ%T3x5S{oDGSTo1B+ z&Rgkw<3iHic5bbe@aS#iS$d`GFrKF3vu_GP15H};G<)ASzXr*C5^hHw*d@TV$^5?D zz-0Bkqas5|ZjN$!*S>lU&=#3uhV*3h4uVw-G9jH#a|gyKp3bYJ4yC zA`^0X$NK7>boADPwilf4N9X36`HU|g5}&rOUq1cCZvB{U^WFRVLkY|r{nl+KFT7Qo zJmPKIe-#hMtnVCO)pH)-e$w=U<1u?id=u@V*vo!%M*pDaGp3x@=5&$iOVQ79`~l9} zzGCX%(!&zf;*;3ZT3^nAlN?XeL2}xYvm8dVyHv^aIq;y;JZi{2dDqx9U7^(J&R=$PdkBbwh8waQLYcc-yC$KKLm&c9B@~R|h(W%wC?#@v!{2-p z*kezgG?sVv;mi2L-=pKPP)6xG)uH5hspYYn=3>ZL6pLX znV~_07^+rDc;v&02O$f)z`O|Yw3s;&@i7sx0tZgM?K&q#xjUAdyLma?-rU4tDwDc} z5fvI6g@l7}fp9L zb_aVS=ZMfy5%ZAF6SEUW_jE*D*n|}zf}8xqpZrlcaq4}9geLN!n1yXxtnVntuufqb zK=k2_l6Xggb!7#sS-6GF>?4mZiKLW_p!rD3V9iXFONhy!l%2av zt1}qZ*Fm`y(J_D#p1VuinoCIqAAWH7;_tp;c6O)B?n&BT{HEQ!?{`7p*3GEpqLSB_ zZ5x`F9M{n$NEWZ#1)_q0jp3JZOw-U9$@*U1Q_(q1bCPSnzV1yj=R6Tjwo11x7%Y68 z3UOBK`hom4vM?94 zvo&^ijNV$APHxj8R8qgz{og))(t$YM-ySEPZ&ubt3i~voB^uiZO<{4k_~B<6FZ~em z^|{wp`;4_s{Ny>)ehd3tb(;DiZk~L3C%tt_6f@0F!naAk?Q!T^8!xXqz7EOT^QCS( zQc7Qza`#rVg*#bAHCncskJ@iJzj#gwCzhu%-|(2|dM0w3;W+rtTAyP+V|nb7uxjeR zuw`Z{VD>#jp%W;lRGXnNR>&RY)I!I3v(4=OMnAltkMqnIPa#A>#-$9f?`Je!pU^C) zFg-@xd^x8cNmX_&ON5Y%`0Dv6lH3s70m7h!D?sKRwnY=^PhkKNoF#D(k+P1h%YplM zu9KTlPzx{7cPwO`qhXquQb?r6qc)b}281DzijF+fDEj$h%ya+gpU{tv^wZxzJR&7$ zo^-p~%U74rFXOfIn}<9tQ~fJ{ZS*?x{3bsx>5w%^Nge;T>*Le+_0ux_u#}gV*U!+&D9Qf3(Op*Rv-GWT0GY7`|CZz^ zIfeyG$#xl)t97E1C%IWVu=wk_<|WN~IF=aAciWpamcxS{b8FuBRVp~4mHQ8;yb6^X zo~B~SxUT`K+qJH9lbmmt+Yk3AZ$yULJISpRf7__LWc5z=19z^*I)V z{4mAlM@swKboj28w+Uu}czp?83HLgGw(`EeT>aC)-bX{e{ZMYDoGec}>BKcVjaogu ztdgE=xr=s4?drU$-Di3oK4NES8%yT}gYIKT-d}j`k!}XNU+?nuYd;20AFw3o%u>J< zX%10NBC2uuv-tcJxybP`Pd3N*sYKACtjvJkVPeKs?a|9L%8@mbn#wWpMx;)}R+KL> z6^mnxt4a_jhG92OB;MiXSP|KJ!)U$6Z)stWx`UlDF6LQD`ld9VP!=L$jNV+*APet8 z*+i!?IARxZ??I&KXQKm?l4L6d(DB2crZ3-=TU~Bh+!)>JQ@g%iUq{pv}maqXLhojPOY1r5>3`7WX771q!bwD!U2#+K{ zBA7EMghVg~g?p?K3<}nwDGLEX%!qJiB2FSiB0MTF3wEb*+4GxB zfsoPQ!6Vu_9E47Zhk=3Y+tn!r!}>lfdu<-cqDSylX6tK_BgGC|awbi)tH`YL?VUOo zVgaXwRLcFk+nf94=Kby6&2(5?$ccjtVrbn6GGvly$nH5Ot%;LF;~a)U6l5Gmph1*a z28A++lEWqZ5(M@_>=D^{B^#K8927*hv9NdMG*KF28<+u5>|nLk+{uH4yJW_2!zTae zC%=m@m||?CNAyZ8OG29#aG+K)r`4_15V6FvhlhEflWGAr0o$C32$p4XN{7g$5G4kq8l)M+*Do4Ky61yE`sxGq0}E zYX`OJ9;5R#Mx(VNVe)Vnm5@Pl-85xHP?8`@g`}I1M0oVjPBAKH;c${HtwK|%b9D_j zD2aeG!y^(+RAA8}(Ex-}iP&12Qmc`O`v9|%GMTA_JB##CItv)(s6YI7fB*CcKSnCC z@7#X5pQ*i@^0(iu-y967_&Uyh=mdDOTTy@sgKGV8cq52oSY8&PIUHTr!$m zD}`_6c0RUSDpWfJuFIaMGR29iUl(e9jM1#zoaiX8FwXNFl*u~AioVq=`i`CTcr)L< zy*u13@St(F>1{@(lBp3N+GvIy!z20_%xTKZlkqO_hQGT0^67H8QJrq?9}A!9aEL+H zHQE(Lk!GZb`7QgvtXs`=rk(>&|_&dV3nE;2e>Z%am>WPWxp>4C%yk2oa&bKIJ>5$`9@&vkKKlkTzzf6?h3X4o0 z1g{6G!F_cFh2_2XgcZRW1`j0dE|HY@TTN7u}CR`o`tLrvKS16fXF$> zB%+29!@&sxb|WU#EeK@HMC24OAd3)WP~;F7Hy(kpf!HW#q29M>!%QeT0GSq52@K(g zV2yBu76dX!^>9`qu@U<8?fIYo-~Wrhx(J1p#OfWpdEX>Y)>m(X$8Zt{msHZ1qT84c ziN|Pta2744){O=+HJVgSd{po3+(FdlM9oM_%E~NLK|Vba;^yZ5=HcPyro81iOf3l~ z0fAzeIfANrlGs@i@_}`Dn#8K4Y}A<&OCvT3LK0$yHK7Ie5Jli&H9Ogg+vW*;eXmq9H>GPiXX zm2hgRD!t{|TIIXw2-ryY8K=~>?TtVW+B&Nl!`7I;X)KlINpixlsV!E zH|91#qzhz&J_udI6D1}j_l;Y1P1G+jvRidG8t}n=n2o(-x?XGFM<03gDq=R@Cfi~@ zku{o_RC5;hP!R}{61n=;KrVR-YFv`QJiAklS^*ATxD6y3Ghsia(Mr{pcV_ee!dZtmJo{)6A09v`Lu26nDbIbWj4`TQMt zVzRyOr=E(L^=j+jO>z+T+Emg6&$BPW(Gb1O5_KO)R1{(s5}LU0eMy+32h61eiX3=m zn)+qyiRk7^){*D?G`Cl=L(NAd^=&t-W3}~_o+I_{`uMPX`EYX-P8LqXRAL*`LJYy# z#uEFb^(3)IIY<&d7(G7t*T1-YbzXm+Y1r}I{ps$6-j#ar9+^hD2~6?&?0L_}cl_v1 zBfk61-UePg-c(snnZDWhDE*MixApeNZl}C;JzVPPE=95&+;8aAYI)$7*Cx4K*M=*e zT3oKYP<}t@ha0h3rWfxYV%^-K0h?RTcZn478rwmiKkKQ+RD3;Y`>xAf>h7l(;9m9} zZH(AL5^OLVX9a2U-sonkXWRspB0S>KsebLBM_ad^GtKY0Y%w!&7Vkdun0Dv8Fiv%l zxTMs5gyhn9;ZBx3v9v?P3u5-DSyShveG3{Et;rj1ugE}%LVOHd8|-yp5?-T$MMFeb z+=56V5aBe=uFSz0EPerJc(1j>hDV|Piav9F8O#Cop0R$UbPV)}%Jxi9Sx%~3N<%~` zwpuT3%k}lS>-%&&Wn8ph;0x{^W!fhSq=S~E3bqkFM))ugGa|yAf+E<7-6Om*$8d#N zV8Da0XeQ?bQXvks0nSVo?jZ2Yz6OLv2;qILHpKUE<9rB7Nu6MUa4+N|h?q^d5W$&P zNVvN9YUSI1^)LUc|Lota#%WSocV*={k-3bKr=rUZ!@QY$C5~t`s<*m1P2p8_wsz@e zB_|Ar*?dSLm~R)DnDIOvB(W+@p=MQsRs3c-loGc$ayv)9yPZ?uklC6=fo)w9oSY&F zpvnpC&UsNH(9Q_$Ev$gam}%2+1Uq4Po}r{xor-&rI5Ts&5H&{z4KgC>CJT?vAS`U& zNEU8a2U%huN42brU)mV05DA$>;#<< zj%dnRWLOPPv+Ug{yd01cf@7YeT~w31MQ|UL=X>YjT@lhbly{yEWW)Qgv}6EbIf<&f zldYAzv3KKOcLWK5PC|PBXg~P7Kat0uVLS79b)B|)?%#TQ{DHoF?{)8N_V!kLyFTsd zw9K>Xl>>gfD;!(zvl)CFp%UltOq7KOO=(G}KByFKHh5SiO>C#U7v8Cxix61L>~E%J z%Cqg!v`;rV@078lO2xL?hCD8t+&$j^&fRhH)JakzVrGrL%V@|aU(YdSx1F-k7?LwT z%-pFz|JCJ1&R81re0Ot5D<4V{w2|4)9E_VIx=|G4BFiiLmt$Wq=b@KZDU>XmUuZum zo845hA58jb+)f@3yrQ(PdubXYN=cWX{N!VizWaH_X7y>)ySp?Ur*z4Z$lDBy>FZkB-co@Jp<#yDNqiY z;BiRn2yNW0Rrm8UB$z~UNLc|EUqmX2QQMQwT9jztX^EQqSaU}!p(W6nO9h2k3R+1D{HPmzvRZYRyjujsc% z6HlHsksPFOo|3R*n6q|oOo@GjS8^RTSnyjB3LZg3I0zcS$el!kgB`)fLJ*;F(K5^k z;7~?&CJ-|d#jw_69ZrqnKpIIjpad{!&~G_Wh!S`P1z}h29^urkb^42c`rrL`|DWHO zRoNJc6pqm)hAs(-eQU!zQD@|7T1MSe(cGdkbFZyY3zo!TAeNLeg*RB#e3*J4$!(bI z`_}d*P*<8coo)}up~EsUf-+Rdjbji@#vUNFnaIT=5U}0Gk=m8| zXuXY*Y;=IO7w;OQHdit8sEwI&;qI(LAx?xamWe`gxo(4tF>7LYm^pGJ5o?V{r>!E2 z5|cHfK$tHRd>0ULC+`GkAF-TheU+PRzDwdknsO(ajg7;h#e9&vY1%#a9X&E;T%<}}V*Lt=$U(5Q0M(K$*&nrFVmwYFWa`zYb*kOusa!d{+ZoUH7mxs08yTE#|p zUfo)iw{PzsrsZDet#udkGpB}fw00fa&VBQWT3?w(&8;N8dx!RPJ-?hkF4d)gJo! zd)W>!WBcW%AM*Ltu%S|a`QAzKb3JjMcI)_jwd-@ID)S<#SVo{| zOA;GJjq&P1B8wMxW?VMdHdvkJ+*;_+NIel)QelIddq?G7l(x_SGa)0cDWb>j`<+}r zM*Y_HNaa3s)RyV;gvkdz=)T1yU?El5VAK(h*gqjjAh`&(C(Z)QeHdL{9O$;TSg12e z6*m@A5x#jyX-qdaNh+{HC)cG^l$&u|NLM7auDSdgRLKyqkCgb;gO*3 z&cW1Kj+vqo$!N_1cj92`F6FR~_08KaY`BDvh^Yt?B~|v+uyHxyYH3oa-oAeB7SUnY0qvB@v&!z6D(kf?&&c3}>f^-KcnLWNVKlcC#?^6r*qEn`3Kc z-F&sMk#cd*G5`ym!MbQfGeVFlrOcxwZhcM=RTA+=(W|5^5$-ff5wG4!1R*(vfhV#- z5FcS7dL*2?PBK8+hqDsJB$72O5Q9R&BZPaOZd(U?k6}Xc=I#3S@BfL?S!|^q*$ZyTzA3L9NxW?`1wI`c_xzhqyVEGWOa@nWGMxCM}t$iABIk(;|%%(^P{=kfC$Wpa zc|g~v-<egZ|9bPu3Sw{8TwVx<`9OXu@DazURqh5ZgH`dT!d#?WNfn91c0uNU4v#^De>4eJ&MwIaS#89KiwHWQ37OYE`D9L?ek zIfYBVPPD($#GH=CMw9{;jY(TzB4Q`=m_%%El&!KP5{{;3XEtHG4nFxf@_B`PO%cI& z%}Z|k;NH_iCJGF4GAU%nQywdLefBa-58Ax5u#H&JdqrCly@Rb4G~>$mkL4hGb9*=) zvTStuc3iIQ=~_R(uFnT!p*O!<4!M{*<=#mWg{Uq^ogmDKJ=mj1garmWcZ+dZ4U^{* z6cS-b93#bWa+gBR1g8!V0USX|h=s!fKAaNqEEqsxRFazl&_P%c8!>|lRA{s?;i%RbF~_>OiCOgu+xF3@MGTPb9?hDnI|3jcT3Dwd z!`U1qb96bLXy1s)IVQKRTtKyXELUcM#?F+bA90}m5nggl^^ep_xH!b6V+ye#>%x*QHsi@H|lp@J#_~BtuvBNd&$Kju2D|3DB_l(A)Kl?@f<+Glzqru7-4m3WBOr77T<3i4X`(63hi-@6XTe*#eX87pcKhB2i9D z-!EAY5s9NkAZ%lvAi;#NyvmwYf;$isbD zWe-^rB_=J#*+)+*gGR{*c4u=|BNI90(IZV0jk5FL;d|}jNQYT9Euwcf)5Gm@cRZf* zdFIK)*{#XJdSw=3gqcr?MU$!}7fz5tqT~lk#OVT0p@!i}atN5a?*m{3k%BTsbMi_t zz$wNcgz2PV#2r$c$=ezvNPsI)B|IWQ*`1X=m^mV}CZh1}Nb^5dOcH|N zB(ZNHD&b>{P!&fnP&0s8g%Kqac?A~>w7Rph7cN5XqlD?iD#FoKC{&Re3Mq)h!bOB2 zJLrAH%A*F&GRWghmYF%Eka>7G1^WghbFp^y)*(K2SmHLKlkAsK5e7ALC}|MQNRfjO z;!|i&ohgh|Z6}ooFbFQ4T%~9X@)(@R$+AjU75A)p51+)=T@J;XlNtdu&l=$&*?J}M zl!Vk0r9E~{-Ul)>yGZh0J38&$oY@U7?|-Ck{?6Z`GV%JAt=0}Vy6rE2?)_(PTYKu? zt?l$fKfUskqFJZ=qE~#}&Nh#?kD^Sm?M6p->b+KKOp``|^=&gwdOXb5K>NPttd2<`bcm8Mp>gB7;byo~857RWwIjtnKkIgenC&ktDL8AHTPAGHy=JNTK zKKH5UlF7R8=F(oqo12tQhy{C<_RTn=&|6E-SnmSgRXNQ2QzVfW^zE~s$;*;%kMct; z^N&jVCb+|H=X$Y&n_!&DC{Qn4G$FO4Q~i+fn>rn%snW&DQGD~`9PNheyFrKP%6$B^ zO>c5b7OUwITPLZBr%}I`Q9~ySCoi%l(eF8D(}x_JI}kH{DHNAwgFtm1HnGl)ctm?)UsIV*usnJC!7N{;&UaeaESb+@ra>p>75BqKmObjn~A zI0DTqvw(O|o(PDsMe^+x|MEZmZ~yd{*HWps4H}uUk1d7^!`99oQ7EsQi?EXuFbJpP ze0OSNjLYhl#CJ-?X%rdM$QP>Oa%6gRIP68%zJ-__PueJIHuo_YrL zXr%1U3K9TXNC0S-fQ~>Y=@2jlSvYhKbu5S=~G|WqkO9!~Ng;yV75AdgM`s6dneH+=jpn3N9C^A~j_i4R ziZmmu`d&w&jImwtw7)hUI&EQlW%}@VygTKz7ky-*=D}r=<3uFho*)sS{oEv)3dw!8 z!`=U%A^hsqu3Hboyt|DtW_ijgZ~NM=q$rZIqcDb}z{yDtavTSgEhIn9KnxoQkmMi` z;#dYO8cJ*lwg44Mv^Lw`+~sR;Tkl%yDRa&-#$B?nD_`HOPk;URJv>&;LzzFnJ)jia z5Q~=vF;m+D6#C$I-7J;%w9ylu4!C~mO=7Xkj=NoV2HJ6TKCJQbUTN+ZNZUi(-xMXE z*SH+0e%t6x+8!=-_Va===G&29qyZ;LA3EGdE0o@?^m(~%h>tqGi4AB`#4U+TkUh8X`_!M-{cV00;kQ-*`Up%8PKqwgFG%N4o>!g^oWxSXE98I} zuU1~OH-t_5zOT<5Y9ACXPGj=a66FkzIOevPI0m|cEbk#tAv2N&>^v)X?VJh1Fw(jx zBb^l@AU4Sfp>b1`CQw*e+<+Qtfm4}|_*`J^5bGzzEKc&2#FFv5C{q&3jjkPm=h<$fTn^F zp~NXF|DRbxCtlnBob~Kadw&>zj^qR|NOsw zy5t&*a1!mnPDnloGZSV>=nZfz02$E88_q{8uw80wOS^8&IFL^zx7H^>1(Y6`h&fYG zS7l7ioRM}zelbli@5kfK;W+rThjf#TD{UK8S3xzRP!gh)fC`g&Mj;KO0FJI9fsAH} z{1n_H2Ei7f;p9|#NYE1kvh~PFjtCG4DBYt#kC5&%Q`w+JIFSk9;=E(24uq)S39K6@ zAt$TM?f|@6fb&22;wP-eJOCr)5rNox0Pwb`p)CuANdy9UuW2fd;}N)oKeEUQ({)F*xZ19l`QQC zzn6D^_YcV$`W5|AzrN7@E5d90=G`^_D1P)he6(+u9|w${!z(X_uAQiW0Id_AA)xu%sT-YOIv4|m6x z``cs1NO<`qgq8u&1y(4dov*%bEEy%KRXohY44BK?Uwrfadm@Nom=6beF@sKXv1U^G zVg?HH9SX&ud;uEj!Y}euY4{1MNQ9MvhNE<2={U_EjWi|yj>cQtdfn2nd|0M&P-*zhV}uh$hfHxY)6524IHjzuur=4#$UoRruf>&J9Yx>UG{JR z#B-NBs%INKTgLpPc3&z=0hVZ;g3le{W zX|y=B=WpXu4FjgzHt!HJcLQHN2h-3Kf(=oOILC@i4F=&zk(jGHc2b8}Q8(y-&48N2 zo?3_K0PM)JA;2Y~@D5$bdQK;$;RDRCYz01j8^ayYjgt|r!S8C zAG|r-?B*SCs_^_+uh;e5+Vg_#Hr^cb4G+4o-Fw=nsE7cZq(~`2s1zCy&=AnT6~ZAb zIG|qK1%d-N0S;_L1P(?S%#Z>-J3+tz?FmVM#odV!lY=V(iVy@i0)mnPK*Zjj z>&N$gu6=E?uG&|UJ+~9G#F!zoj3cCi*LSuo-Wx$M2_{AhvkQpVzWeT<{nP*MPrim^ z#;I4uj43lYqa&at5GLc})ceZn+8aR-%JrhLo{|il2W}maRaef*dvi+e%>!F?Wl};k z1IZ=ga40YLhuhcl?l2w?l4!^Pv?3rnfU8lAt_!7NOi~guAR$pkH{%YJU`S*Rk{FN} zLmdI5d!&(FB|t?mNPERJpc?q(we4<;w_jc9r!Xg4EA%aHCm3^Fw(3KK=cr4Sy2UUc z^Z=l-q?%@Ip0?}NhTf16=EH8XH5^olh9VOcrqZAMVQbZ{m^w0Juy1+T-@X}djvZ+t zN54LWO}ux6!7mq-WHDQNN+LY%IE~OAD`;JwFYmE}><&}eA9lP^858!%v$w^NrEeh3 z_%-#d4Vl_Ne(f^Q^FzQ0ATrIeTYMO4_ySA!i1u*d*7>Fa9o?lqUFXX;eVmd>-%iU% zV@YX0Pp_cl*X)apYb-POZdz#zEy|F z`5_HED(H^v8&|Z7#_P=YkDc7W*Ph*$t4(xBnt z8IwvnkUjD|Z^?aO)IXORl?ZBpMY3(S`RpC+fbxoo>eI?(@65 zgUngxk#bf*ixkl#y7x3Qb{2$0Tna&>1QdpW7%r)iAh#Kcp*Di-X2|R?G62LiVp2vY z2xTleR4oDxgKGeTpml}8K^z>x8~{i*sN{~sjR75+YXzjRgeiw_7{#k$VT{gy|95^r zn5?OyvQbzyoFPSqRKpUG?&nrb+#EVNQMVpZ*f&M)6=Vcb0;TaF>d94z(~MDO5zcIw zGEf8DW7fb4TjiYqWOt$HVSz}DHvxfxAS3y6#DuPZj#7N>0O|osBXo*>u|8thw)UlK zYrUOS7;9}!#Cy-K66zz0RdCBWAz&h6(auHCf-oh;Z>9)*rf#&4^KVZF`#!Hj!+f09s%YE?>Tw3XX`Tt91Y>J(|=j zuqfXEI^rez0LkTUsO3w4_|3atUzaBe8I#1E@%Gh3R4AN82r$x!mUYb0oJ!OEom`;X z*XaAC7dIh9EJC-$_9~|uuOfWskIxF&E8}^imxAdQyf&Ta^3kv7?U@;O1^*q73w(Dc7Utv4>k<0ul^bu_! ztInA~8_f}jwnd%@!XahQupvtERe+j>vNw+rb<=(+eWdt^FsM^f_3aapL%AVg0H(o# zk6zD!M0Ew)^-m`n+-24UV0{mVqpb$ZR$FMTErwyz>5H5DH!t>gl1h@e){oEI<4IlH zdZ2k8Ztq7v@!5QML3|C!DUDDvk>?Chl?Xh*%^ZuH0rqIuAhxyva+q3}V?yKrCvCc54F9FYQ^QN%4Q z^MCr)@1O^y2=|_uY6T(|&})rcye_b;M1j$PN)Sgg7@0aCvWJ!c>eX>zj0BxiDG3;c zTujoGOO8T98PS0E%x50QpiHp@Wn-qahqeJ!M?|XRTa?nG{oFeG8^OyqfhNaPj*84`m#M`k7DaG=%;QIG)ARs&<8+`s%^9gqM1 z{}Oxk({tbN==pEfk3XWsnHKx-{QNNIsSJFk@1FI&;ms%k{BT*eJlzP@1|TL=@0I8M z*egpj_3f#(%eo<#X*}HJ)E8{AZIH6?-E>gHz8PjwgFJ$DRjrFpcc0zwdB2y8sapdl z@)z&{e$7O@#%&+I% zeaufV0QDo6tCH~oQ91Yu{eaMrG1FDY65A_+N1KTH4VO#o3fj=CQ*D4oO=BjtJFeRL zg)e4y(&0Xd!O+BRa(@f6HM+rP^6R4y1E&$WK@P%w)L*r$d#xP~%&Fg%*u5Fhuv}1? zh|L5qXD*5`;O6GeT$M&rWgr-gG^|jZ8^zgpq`JCnsZro(&!s;5_1*S#y7&#Ou>0g?-g+AnGE62?)&qOCkm(@fD(gdms`8;kDD?Qplf? zunUU@5TQ2jBcTK%g*i9?BZUKy&B2bn5;A~6NbteY1kEugYEERfXIp`o3(-MrGiw$@(zX_i%2Aj+nj~T)9#S!|U_=Zh3gHyM$pA#u6?|26MMvTg zcIp^J2-aPh#SJ;LXk{Q%BVt6sEDj3ZS&_gIsUsBj zgKbfpUaoMFJnx5bF8=h;uD+!iD0aIv3<%xNzKiYI)2_S0*kN^WuvD((%RC^` zq75lWd5K$R51*HSOl<&KtcYC5^Qw4A*1eZfTMUcAtFc|XbmG^zKIz2ZdklxQ0(tQY zxmGD@JvcRxB4mM3GMk%iBIvl+K8;Sam z{ax%h)eF!8XrP3YN|YhZRI+h*fJN5`%x+!XB?VYhaBOJiY6XQEF|2#pv3JLW(4wiK zP)S6DZU*EK!U6%ID>4x~023g&qi)Wb6UT3aj|!4^1kjg@ z(K_6H1@%)p-qq(TmGHWGCi7lc>UAZfhz^LW)-+_;I)N7^6vLc+tI9(j2Oyz5=3&gy zvoniiuXmr_9`VtWSW@PuKOGDSeRuP01INMvTrrQ{T4!eK@+cJ-VI3_KwTCwDZo9pV%63-m2;i!M5@V;?cVGpfFu381zlI!1c;a14^n(g*-X{0pivOkuyS5PeSA%;DlT-AYdMZ!*Y=t zRtDGV0g^}d3Y19&325#QX6e1@m*&hNhT*PoZTr2g^Jf4u$Zkaxh_sh^Br zy`=VlMr$8)sWKxw*lHejIqMd@4RaZ&>~cSC{nAfY%7d5NX`&U*b}=Aq5bWXbd|Id5 z{Nix?hIU2DdRk3*TLB`naBu41*fEbDGt(xVV3#@FxAkv6o}NFQ^1v`oR?2Z0Vc-o3 zTx)pdq5;4-I$wh#5V9@pQk~dFLXqa>Sgv|S_{^zX26=cFWXJR^&s%JM#j2E3g!c+$BtQ) z@o+V}8LatqjSXTmvd?1`h=-7$fgUyf$fANIo)OYU^$CoFva-;;xQuGvWg+@I2jlXxK{NL#10)d=JjNg zqfH)XR6;U?%qNXfu@5E_TrR|ByD7*R)MDS`+P4Npt|zDZz3*SQ9(HQu%iZ{DoL;<0 zhc_jivYz_W$Mw7$lrB9_L}wGzlM$iR$CO{#U2(TOW3L7-c`?F_&Ee3WNd~c}f~L z-~12%{XhAq@A_JM+a_W6U`Jan5gYP>}0}~F23m`im_>X_^d+r#mM`8!++8{HW&njyVBPUI3^Edd4I9fWR~&vAI}NWiF%r_&>PY{q9fs`B(kjHS!@y;riHq(f#+nWI5&Kars7vfB$|w z(oi3_uMJDajCfkNPH=lHsgcog>DsNWt^t)3Tcd*fw5$Oam3%iH=DJJCJ1h+n2Vv;u z_VL;!@r%3tS2qU+BJ7;0pF14PV1%>zpj+i|6J!Mpg`2{=yY>0>{Ig&8n2~30He}C- z!vG5gpoZlPWspRWcN*xm8?IoI)LY$Xsl2P4$5Ozu_Hv}BUv0bV<(Zv#a;$Ls!<}Am zzou=^@mBL_*QG9vtn=$P`Sl1&;|5=ggEZgJ|21$H+huK<+8)fBg5lH&H~|nv11tq_#U2sn-W_%x*Wh3Qw+J9e%%%WH0MNnA zNQ88SG(l9;?o7a()7GP~Et-x26$Qi9l}rqPJczvVKlst#LV!ro)p#{>58;4{FjItI zdoF?&Cc*@|by$c=y)d|W*KkgV*agK|F%LFz;(|j0g6@0}U&4umyd*N>DTh&niUTkM z0%9S)LS`p{#uy0FgPD3mLmD-&V1Pyql143|WN9B4_B z1Q1$a65TeJOwo`)jT$e88DX0JNB`c->5DJ%=|f9o`N-SPm-mz2yqW!DvQNu5`yih8 zA@#%cudX)TflyknPan78?l9dVZtHcMt2S@YTR&CjvMW|i`??Y^4T-1MyK-4u#flu@ z*;UOyJ^RIn;Ri2Xem);r7|j|cuLP{aK;Cs}Fs0x@H)Rgm?=TJ4Yi#cyKRrG?#I!5> z!P+n#r(wLO6l@@Y!rF-3EVwXYUv-9uXK1U>H^Qtm!qP@t;|5ZEjZ433EQckF935o46^5fo%asul{$KBeBIoiE$^^L+f*)?%4X9Y_619c z;R{@U4lvNR;;cq@+&>tHY(@I>lDD+n67@b}rwOhV0!#Vek!j~DQ`&6J%6$MjD-F1r zEN)TA;@yX1=P9t403^hgc&`{5S zTR5888f52-Rkm_uVPg{X2m=Eu=nbeqMuBiLVr-6#TnM5Qb7=4Y<`9NJfq@_r92B5T zphS#B&J3Z1g5gLhbm5dBaQXFLT;5%+s!`$HI1iwRvJ)R)2(Q%e!-nRzC zNUf_6%m@&W&{Gj~iykRwGY2E{ZIInKB{Ff@hG{qqvfJVAm~QU!h?RsAd+!}(?_e8E z*_v{ZRLaCcMnGUaD6w_OL>(L@1W;S-0(^v6dD$?7v$~c*#^}Jw;R=v2D|lfGLIui< z3NU+Lq9ha`^y zVubDxz&SD_jVXXKAhCM{CJZn$P5_Ju!vGMFMBIUb85#h1;H3p~Xx%v#2QDIB z9aE5$a0@B{Os!YJl!vvpO(6u70y}zeRgUDLlJoMzzxTI>pZvhD9|T(2e!2eDQC^L{ zCwyMo->CoKV3Xtay#7^MtCd?Gc3Lm6;j|wxw)6E9%NH+EAEWYl>0Af^!nC>gFzDgK@ap*T%NNHa>fM!tDOHV>B2Hj(UCN-(KHosEH0*FBoALb1 zZ{L3B+prr-DjibW=5ffoGkZjUA>24Z$Gm^VjxS zxqRI0v6Y)M&7V!N!a%Wsr;2eD-}-git|!ZPJS0L$dcvDqTFj(-9s}~W8f-xI0{uyM zFR7Y&5IslUNfIAc*gHleb4;E9%5pXs<+LKNm0zU(5UQm`Bmmm0A#26C1dj0BBhKW> zA{ReJ-T_v|9M=+A7q~sxb@gQdZn!lI zh`w1Jt{C&}e)l4cpXc5FFizbs-`ls}T^~Nx$JW!U;iinG;`-!1!tP#fQ=*0PKJ6xE zV{Oql0P^sT9N-G>wS#r-4A@LY%#uafH(#O zqlJQqV1R*;SywE8?1BzJNDM#_!4$559yqth-z-1>XbvDy=8}O^Mwxd|CMoOXPygcK z>uCGA3@ML!+|PMG;vhMjlOWnKPw61tcVGX@|LK4DlizI3d#p@J01*_s5hY21m;fk1 z(!+V{JxMXsEOVGE0wd>~jC`K=aOus%6FZo8L86dh-i=byC^;h>r}^$?&bPa}J#vOz zMoi(=S+N3mZ5TijhDgO&5+`t^KnQoph{zEHT?vBVAYCE3I0PhM#6WKuUSM$!`E zs1QKTXwHCz;M{$P!i1FqiOD1)1|X(DcSbXab3j3=)O*+*zC<7n6T(Jd>$QdwAvch9?<#< zldelA>OcTs&7?4nkQ^mpO9KiB2egR93`oj8O@SRvBa+pMZrVYU87I~N?~x1<$Q+Y{ z_dxM*vgUy_h=gH~p+TMkjSQCR($(CCA$bQBZp}ii15gF+{qD|w{D1fl^EC4L5$m`8 zZ(#Y+ml>C`zFi*kcKm#z^Kk0xhv)U?i!}4FonmvdkX`cAWqr5#VIFU4e*bj2+QrL$ zR+OV%*B(CX3fY2O*gGS0ioDg>O!9ml#_7f3^{Z*ZXT}76?L5-@sD#m1prloBJ9%>o zjKiLJ-{555{ObMrh`0OQoC-U)pt4Ulo`V7s(}spHChXoKq&BTBXe6`14Ff<9_w7DI&Snx;oH_4*A)KLDPbEaw?6RL67WU$H>nHm*P3sn zb#+8_npjX&ANyZ_bKUTqUtzwfulD!-QEt|pvO7D>Wjpl}Aa~iHwRw74^f=}ok-_0! zt`9^j=Dh>Uaw!f?alBiku``zzQnoXbNF&=Bnxr-NVQzp&Ecw$_&bm9%LA30D>3+UIun)a6<#) z6c7X+PC%Xn+zAPRgt-xk6C$QW3W!L6pv(#L1_%+f{^g(5Gb1LDA#>1J=m0d`5kH>( z^q0>cgXTQu{qAOuWf<=7hqSmS_nGa=)1K}N@Al^_|JDEV|NW>fzo!8yz<0@a~dgrN{A z0$ON9o+KI&M&wArN+Ft>h6;dV1Sldh$O6a|7f-h+j!>vIg^ZaE2e2NJ0Ex8&yO$gO zKmGJ~g2ESLN2Gw&w67RJ?w$)fl0#5fH6rZD#6w5Vj+WC)x~M0k9OfJ?jq{iyL(?%2 zMH3Iq7+C<&h=3S{kS(}CZp5RaA~=(V9ndU-7&~-CR3ZsCObvVpeRRzc-5a{PcI`aq zwJnNQ$j#j&nWB3K5h6ee^1ukL8pVf-N{(ef_E-%G61ZTn1F=C0pdcD?t&wo>4pC?r zLBw0bpkOA0j2=T_aLNS}cJthwz}=A;V4uBqB<|?gFi0aZKyVtw{r)rh@_+w#IWa!} zyuS~{{V*+Fxqp52!%^;2#AW*i))mIz-RG#w1Fiig6^_g0@?__7JKr*IxIS7l&cncM zO=+l7b(nV0d;=p0HQ6OKuxnhmEx$aDZ$7)5`Y`S}XXgNy6xE|hztr+7v^kc*bDv*( zYvpz8w=b4&K79Q*Yrdav=G|m1Eivs#UL2?BKtzI3D@Q`=czBbRN39ot5q$$kv;e_) zao5)z*S9fVw)ahs$1wvRv&P;R_72m3`Hmp5FUJ^i*tW-p1N6XlCA%f$|DG4IA0GcpXMR_slu= zoS$I0<@HkG8eL7-`j^*>OEP3?U?~x!S;du*uSf|} zO^dDpeEy)*n^-qku%EUgD4`Onmne_FmGJd!gwSPnpL^ z88~5Z%CR83w`wM4&(_f#BEXFx6x^99dJ96N8Lq+!n~YkAL-x|IdHGk;dI_H_h5gZhl36@Iik$}2US0KS?A!0^=hA4mpy<#4bIzZxR#1Xw4r688x zJ&EfzVR%D1oE*SATcmyA-UXs<7zI^> zk)sBaIYeR67L<@ZpjS+}NN|9HP*lT0pyC#RUb|5X8YvnXA`l8F5Euk@G(rM%v8{UG zs~?un|L6@x#M8HJxc8fx{h`;o?mo}ArO>s#`?S&L>yU2hv*|;%H~5o%tnd5BULB7= zO+(+B4VsIL*Q`vH$z1V3XyDXiCB6s(5F%zaV>h)Rb1~+>slT&LwV^t?W+{w6Z zupg%4{d?{F@Ij&GG>$jBB!p8`IPRn`M%69}vv{rg;ce60C6(itcaD(AC)T%6W?3rP z;xs^C3`w>Na?o^yGH6|BTcKTXKg8AzZu$AK`yf@hMgt05b>*Kg9>E%t@&Dfsx!()Bgw(c-Z`R-Wc5#M&A*KzlX zd6TG=1{Ne@=??%59X;6n8pc3CdbQpZQy6kex&}lA8bJ)8pc^BB5CR4TKoaT%h$0XM z%-{|{AOy}VkcbTnlZQGo2Q;Dpa)1O0!x5>lRbmDfA}4nzL^L#se!c$LpRIjV3rEY+ zeHv*VsD47D8SeMPd@HhofM~2AE>^1yIlnv%cl$K@)~8?okN@=l`%k~F z0E{V<=d$zY!<@Btp2(arR9crqi5Q|n+fGr2e1DA7rU>Z92`I}*v)XFCr(7td0PGmU zJRtE1T!i;Czqr|tQ=g8jL7Tu{4}9l3JJ zXb4^wH7QO)xp>k)(vF_Mvnv> z9y9AHumDYQsaP1d?mQVak5SrntJ+mJ2710UZ5st$R}+L$q&0>XQh<~wQ?}?NBcZTW z%jkh(B?1#>@vfd^Fom4@W{^0u_beR}XoX?6wPVyK69Ays+ChR45CEck7(#+hL6Ds> zF;Um(=-^O$^C2a;y^}Zp>;H)RZ?pmLJ`?{wzUh!&rPrEeh2K%pr=$Lju&G+(*NBfJPLz+4dENL!P@<2H-G4$SZ!IiWGZ_SpvZqB!dyuZt| zQBaWD2zZ```oZ=)rm?EQvVmc=ECT7aBh93;06`1hKFQP!_Vw+8*K4zE8?F~^ce@$p zAuh^Helyy&?-t8Lw$}5Qts9$vy0)i$-by1u z5=yhi7n%*L z#M!Arg)n1d93*=4kfnA~TZ4Fkbij0fd;6l6yO;TxWdc1v^zYuSC+-Q$EiqSYVewhq zz2-a3lC2vt5<654t<4&_bv24Ly4luzJGYA(6+o6^&;U@83kC`WIFNM2;*9Q2XcXZp zkre<*5~7n6rh&~64JBa&vPT3GMKDq@qFW+F3-gDaDq1F1c-&`IxJG>Z&VY(et0Z8Oc_4#Rgy4KngO?=Puo4awJU>u(wF8}(! z{6~NOy(45)^w!uL4m-|cTdrxK6c7{`oPxJyW2P<4+Um=~({Y%E+&B$HDmfu1Gi}uY zbK^c!N%yyUy$l%+)AZ_vO!soT%fkRH>gvdDO#?ZaI|q8BoQQ#@6lrAd8o+69Sea9p zlamvo2y8Vn1Z1~NRv`qVA{2y?WA%JM@5lhkNZ{mP;+g;|QUYp-3@JqqOyG?L*s%pt zKp`_kjtGtjk?_IMkZuD`h>0l!6ZXn~{L}vh66ZkE8kmFu5JU!Bx1{6+O1B0O)&x?p zWAlh0RsjdcNR$gx^PF-)&525ZLWTC3FfdU_0bvkCbO2`Th!SxHmdFLIQ!>JXQ-EKM z63S*$AOHh?i&a5ah?%VF(jp9(+FIXqP}8o`Ep5w&1e-xOB?O7Ufe08}xg&dXbaDg| zumChlLvJ;+sioA+Fg1jr?5qV4jlFKpm`v9mhz>!}yAV4X0wDrKP z?u}!@pw?l)uz_kLQLw=+k~MH!fil8IhaF2%nUii?liGIN4?d+@K5x1UxjW|#L#rF9i_->uL_l`4~5^nS)V;$!mCY4Y!WAxsv;)m#u4P1r0%*fCEX`6j0E+OJ;V?2{BNe zG9Yw}0AOYT3V=je00Nmk5s?C>2#3HxqW}m91Eh|D&Hx^cNWutRFe4#gAprwq;fU&* z?egL2FF#(YF*6QX_MG?k>ZkKxe7)!l^KRaa@M1`V^*-W<@2~HEv3``bc^>!q#W1~k znQ!;J3+J2f|J`5wH~;s4wN!93usY-%3T!QciJg%!CeERTrb`-ze0u~O`nrGyW}jcY zqUD4%NJd|~pa)ubVJ2eCFZLKPCfbkF-OHPs7t_t%RE9w?3;;EGy9SRKwP^%ph=5@f zZ-E5doJ+!uy}2NH5I|5O=%nO`7=qBlTS^E$&<#ouFp@Kk&G}1F%c?(0Dysk8_8te5IvBMtxJSJ;55Ny^RQG{K?V%t%oKz~l7f+WRMkW( z1Q-l}!~i_tl*p-~L$iSJFo%R4BZx=+-9NhB|H0o$*0??Csp;^NUycbr!q<2{mGXlx z*&Z0{_I8K+Y2GWO^Y!f)sl<>!%CcTR^z`}$_sKApYm507wd!Si-lDn`3i58}SWE$B z_tUSAdp#u1=BaF9`+9kFXBr?$UG;|iVrxj@gvoaZ?)^9KJ}vC?ct|DptE)#!hiq2dw72Q*c&Kb-o3N&>FLsz`fh8;*OxzKk_qY_Pqy2a z6DIj&)2p0n%@*!d6y*?jjmDszDPkzjcX&Pf z9Fhm6fj7f^^*o7I3zEfgzF@fr>j4Ru9+$T^3>J5=uC<{WnLR;8Bu&Z75ALSV+mQ2c z`$BlJhws;SPrBadJmq69(&OoX_b=^^bB2nbuZnqg+v;H z24GGO2o+@)jFeJP7f6Nztp_P#hA1A&nLQG501pu%j24LjDFTr^gc!jQz#}Bc%oECn zG&mR$f&(FHN<_rwffgP-T4;oq$DjXv{cw>%gz|XIynpS>yY&~}wwh!b=DUH8MEXo? zZ-4#gAHQzb$4#a1@i^b!?Ou)P{wCkeT=068KmUjS)xY@X4{LW$kr0^@l42RcYZ)bR z3epHoK*a27Bnde|N0~+f8Yh8i&K^-$LrSC6Qyu1=C+v&EQb$e0B>R!?Z>F0a9Y)N| zNs#&`qi9ox?0`mGK&fC(YRtKa_p5+8PpGQ|LbYHc0Ph*>>S-if!H9-T9Y`#okaeSu z!D2mtKmqznti+6<=!vlb2>_G#a1{4oKu~l8N(c@?=pD-lNC*xI#Y`bFAaN%o2Loj^ z;y?cC_aM-{ql>a*bru0rA8~ZmFb(jg;ysF(0dpmiaEnmp3B5uIRFSX(PNgt4iAb54 zfD3`ll)L9d8~`AKSP5_;Bh;Pxo}K{FOgtj`N0c5CiAOi{RX#O|i#5^y%mAd(|KR9^VDmhx+XjKl)urpXfuqzH2CXKUyk` zy(Q-Hp5?OE%@->`SZvj+Ki0v(kN4wOUk!6?JnoGcJ2=+XQ#b?@2J|wx4>W8OrJWZh5{Kmg?G}c296!s@hg-Ew4U&Z12B*`1)55 z-~UEW-@L0~$IpMV`|O&An_;Im0!%xd^qk1iWV{$%Bg(6cG8r&g#z z-uDP$=pfMomGb>=_oLhSwv2(YBibJI?Y6yt?scU5efATj!OF|H*{66Ed*~Em@8r!8|Zmk&-f*B$5f(#2g`^*WgU(ZVdzhi%SF&1tYSNG71P& zAdoW#7)Bs5Aarm;nJ5gr6N*z}Z>DvZzdb>OX%_SVZP<^*=@c*<{3ls!*}O@ z_J8}wzkF{&0OrVy;Y3IYyFqcsTmq1}fSL-9`}^KE6w!W_-(rNPCmx3=BrC=M{k%Dr zh82JYk!X?Uvd4V;vK)uu_J(&e3paoc!B$(qV5VX~%9J(-;lKaGpCCF>Nz?(^1DO?pJ+NBBkv$A(3h;0sFu}~A zPKgm?$OS-BVHt+pB~qD^Xovt4f=q7?( zC=m2QjvX`wp)+A9gjaO}Tb7ze1zw)6>$=unYwy*-g9>!77CD7FAP6!S0gOV)wR4)n zTH#`mHO^Lb*I7%1_A(DCTJx!uvWbQ7J z13_ZZB?LSH>1SWOIR4=u$@WXLJ-IfBQKd+!?i*BQg9Qy>ZM*{Os{X^bk>VstJjXl!*G9(CB2sA3<)q& zLkJ5v9NT8my2UW`OFg_|Kl$-yPkD7s4YHV)LC>kQ zovD5JU`sFKbU4`Iw$NddyC2tW#WJtBe|%fNfB*K!zw_dFpj6kIFnZ>G1z&imUPo+~ z78%gd8dynv*@ib%kCe^`FN%HN$J+wbLs&iX%9785eW);(bUc)j@WZbz-)<@szd00G;@w|<`q|%n_+@+h@$&rkyyasa zbjbTW7P-BfU(V(BZa54$QS0TqpZ)Bg{KKDJmc}`VX4p1#mrUU$2FQ{lAZJND_X*oqUCxjMwk5ikDd+ux>Q;9f&1 zkN{Wb3=l3Xc|dT_j);&m0cGCI3u*+lXb3z27%2s6L?(2!1~@rn$?mlZ<_Hf@K*(Z< z2pRx}5bEGY6b4|2I5GfCJQE2Xic8s{QIO5jWzq)cdx z6_Q{=kCE^a41okt0f2h|c4qRN!4=F%#pr5j05pP*CIkxBP0?F-15s&!{^`>iv22JC ztw+cJUe#EEN>I8Pk&rW?fg_n2NhBW4RrsII7} zu&QAI4O~|!9Nm&gPza)vC4x|w2n7%(*Iugy2x!M%%1(d$A5Hr|_`r&7#e)4PU5%AN`as7bC z{ls~uES)abr;b)Z2E2cfcE_;-ZWXe#i-rjTvUJnjtZ``1hha|=Lh14ODo^h&Jb8Zk z)z}{>w$^gGo5$BA8n`YM7`7#$azbRz+ZkjE-6+CxcChyT+snhH@sQ?{6OP4ToR(E( zwa5dDmD1{Xv?urT2l2LH*5grb?$fmsD`by!@RhQGZ)cd$JHqL7sebDC_Aej4d3gNr z;pyRYdH(vl>&N$x*V^l8xo*RHu}kwM4t*PDJLI@+t8Cl0Wa#I+FUHS?VQf!#=cn?* z3V9c?KBDsbPw&5ab-O=)0dY=Fk)DhP(jTD}plZi8di)tA+RV@n6uDW~u{41Cdf zv~7c&Axx1VS|9hcR!~Ayi?F5Oq4x1bKWF^-HSC4P*Q%J7CqEn`s4k4xkGMZrlL+tX z&=(j+tC0que&=|&m6SQn1Jn=ex2Mbd3(_ct37GK)UVm9;hwTHUJ!b*}L7~0@6o{?6 zdskQHgbq1q3>U~rJhK3s0~D7X3xWVTprZpPaiYNA3J)pl9b_PDWX&0v1x1(uTLO%T z6won^hzZbvDHMKW8m_PqQ1`D?3On>$d z|LcGKrynT|b*t`;QHWJ|B)sOKXuUErJUx1|ju^uLO``!)!0Ij`+<3UxyfE#OxDXbiH!t$-7q9n&ANEAl1*scvF4U^!f?X{q#4#sgHU$tua&&AM2A-f8 z06HUbHtea3Pno+Ru>prC;)Ob3G^7&dAmYG*6g;^Hi$@0lhhc(fDB{2j>QR|WfD#Cx zISfD*fL)T9Ic?rDNskq5ghbsb1pqQOm>`V*{_p*r5XR;pD51gPO${uoYIr6I+o)tr zk(zg5l#IQ*O9pa5oEU-;kc2rpbGS^I8%#+kAd4`dK*#}MLy{;AKnNYp35!cdqA+GR z2c%%a1>HjuL1k+p1A2D^b5a_yopcLZ*XC{2LalkX9)qfSH$Vws*-2j)Mu`v(A_(8l zbUEWZMSy@3I%#yU+yGHWSEC4bHsc^RkCYHBK*%(6jsTEEj9kr#24e$DNqWwrN*FL7 ztt*E?WQ(Ro8e&P*MZkaZw`ujr60X0^2GJAU0;?##^DK{pSO0u?Qe(WAuj#nBW}iN5+3uoKa7w; zv>|LZQ(s)e*kx%jB( z;9S%sVl-+(>agRC%W{2qaO-@WgO9HgZLF1q0Y_lUq=d@r2B|cw>xals*XjPv?kJvw zfeDCkL!vfFEZ}YPYri}`fBnntyWc#1_w~cs_Aa*|4dr0w-eY_J;rz6$*X8lUscCJ^ z`el`+$qp#;^1NQ(pSnzUyG3qy`0mpsznQw`p~Oh&5njxEp10jsuX7|YM-rfBvO^P~ z$f@@{WN`HBmXFspK0Mp`>3O|cY|k(ztOl(a6p0HZ!a$^%`ornrb?uka zC;QdE`ITPl{Nv9P<{o3}A8p$AbM)&%^r*b|x`eYmpVDqu?$Z1P&bO~qx+VYQ&)=M% zOH;&#bexq-nm>n^^FW(7L)mjdCPhGuW{`lAL+?F>H*vS7j*f{5g4hVj1LL_GmY08{ie0=8%*>ONSZ-4P`e)-D}-~94=s>ECMwP$xS zE;AoKdo{m!neXrBo89>3>tQF9FAlqRzx?LE`@jCYXAeN1P}ydPm0!oJfLnd zNKB(%FBF}IJ+uu01A|Oc83wHh$h$S~j)E!mMYqM>+aP&&GwzSO7ca)$es?1}jftQW zGqxVqoihe|QznoM?tz)fEx1s2Xc^F=BO(wcvIds9D-0{grapyknAlOtA{dMl0t9tI zrr68{V`b<;;z5B9y}coYN+MvDT5&IFiHTO>f52^&NL6y$)25Qz%`8bdQsQY32; z!T;$G{ua7-Q$|7&b^-=qwyJ<4qD%sm0L*eC1MW_R*&V@hq14TlvuUEPn5d*e3Bf4~ zGolDWwe*5GfQZ~^Qp$-*(8W0*96VuW&mJKZCCFU%q*qKFwr3~g;+3LZLz{QiRQ%dD z55LyyqROPzz4lGL7s?n3i8w)GbWN#)vun?RD3n_Bk{!uI!_1S1BAI~$AYmE>YaY=! zd2=x!wq__L4TuoNh#b_T17-70-Nb{yn|Y|Cfo5k7qk?L6Q;o#YKmRG*{NWz}KJ)wU zSKp;qU&?sF(`o(Q+ne9vH#F40s6T(Y9=^o;%Z^ri_uL**`W%nA=yG1Z-r%RNC=YqL ztdEQQ#js%8O{q1h&5~6gU|D%L+qOEVLckK^fNdNB4sZYB z7ngFgdwC-%%VlHmydUK_Cqdd4k1_RCaRveGXNN3=U<+_SV%^XE@#*=~MUGR9FX#5D z6`EEH{X5e zhu8Zze>C0n=@|R_yFH(nL44)ukPbWAw5`_;w65*!@zg4Ncw5e!eE2uS;i3e7uL=ebc^-bWBdWx};C>;@!88zxrl<|BLk(KmYJ&zxwd?_fL0J zBZLI0Wou79-Y=cxbiyfFo7gJM!|uzQ`4yJ^57VUHKD4**x62{63bbLG=N_y7E_e)EkzoUvFG0}vVS=8S?lm;JcEdvp8pX8-yy z{OHwm7*fHIZL7O)|EK@A<4K|mpq zdBEN!bAW1R1NY_*G^C;TbzctAwmHk;cK`CO3`4(}fpQ`?E5<&pw zh@6Nhyn0R)At=adngXvufn1yt1cW(27E|IFiTU z5vYd5?u^|KOpJ`jXxG3AVOtbh1R(>tA$4-Mp(rH&KmPdl4UmTfoN3#F zG+{Oo)JkOl%;=~{u~`UEFavmqCn66F4|o0%)$5}0r9U}kVNRPeQfGMI!KV2uo> z>KR%LIg67e912^_BOwA8iE4=y)R;3u;7}kS2$%u~22(*&RddQSx`jJ*2MJR&GV)N* z*~mkjG)SaxO2FQ$j&nCh2FB=+(3L1L>6_o5?*HI_$IGuY#&kFeT;$`Qw@=o;_=Dla zoKJt={*ssLn165_?9@Iyt=AX!Y8v7S59jA!V7|}e>vcG{<=xq)+x^tZb$!G$z2e<` z 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

Q*ie`|Cj&2i?YTA`Sqeun>bF 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 z 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ڵ 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 Bl7)y3z7t{8pjX@!0sVHR)AtV(-wz99O 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�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ෘ%tIeIbKfQGs4NNGLo( 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 z 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

Q*ie`|Cj&2i?YTA`Sqeun>bF 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 z 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ڵ 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 BC^K`#~}+y%;bI`xp2x8GaG0 zCmXO~3xZUZppr`^u~cj>dAsayp3FSW?pHJC7!l!zG1opjlRU`WSZnRIR~r!{;)^f7 z;9vZI{x8eaw-AP(3C#j7tr`Q=~#n?Jk#=H)P1c!;u0V+40)v|4k&p?31*QJkF(tH;dUVRyZ~D__67 zdhz=1^A{IyF0aR_lH%?pBLV<`h#=W6v|H}4whQf+cC}p)k^B3%+uglgZdV`v?Zbcf z5AyKo?jP;`ukK&o{VgIwQbZ`Om>*eGtePrC8SdU5Fal)z+3rV?@Su<&h3$#L0|aN| z0T3XB1d%RZUw^y3%YJuy_W0?uXJ&hm>~sn$suJ#1bEZhGdla`mb!U%t_gVySgc}8b zAPnwE8D_Kt0u+LY1yBYE2I$BM2zmexkzjiiMuyY?87VV7B1nfQ9CQz;r~qsxi^_mY zO5si=DdJOzk^*;4*=iL?z+o;xuo@#g2oVMtR!vDqh)6^sk_UuAO~%mn%|U=5iC~0N z0uZlGK?Fs`BM3%>M@Ta@B%mT_7N8SwpWG#BGBc%8le>|urR1&)ht!Ig7=rMy5fKq4 zEL~2kZsBQ&>6%HYiH1^Z%Dq5KxGq+qLgV$}V6R@iy4imA%{MPzm5Wz*yQwx~Xoh8G zs@hD=%$kMW8*wwQc87MA$A5pPdpvZKdz-#@vxj$Ux8Ga*y+=KK0r!99?(J8qdjISy z5)trFRjZ~+A}m4x2K=2TRP7JA~61bQGs(OqCJg&hYR;3c_HO zR^d({f)bzu4nP?da1eAS7}^sERf>WN4^WUgiUJA>gb0I>3_u_b0oWW`nynImtCI}# z`3VD%fPoSo$FCJsdaVHAp+bNZ!krNm@hBu!6A*xjXq~Dg03LLP1N10LMKD;ajQ|Ld zfGQn>>eH`Ye)`$VPrll|dUIDSz8ByhhT#@mAI92yo4dE#`>QPsw+kty`};gR z2k!6r&{ZBf&;2p-@L+j(_&j{5hc6?-R8MHZK$E&SA_4@>-OUNKkAMKY0t#io5l(@-Qa`$Tga8F@F}b5yNlFqSg784NhuMVi@X8R_6s3ff zaCbMiuu`Vmi|y4F4*Nl1k*bT83b4f9Bjwd2O0MR={^sJd7q5Ty<@JkKcZab?ybZwL z%TL;chf(=H(`dg^RS{`d?|q})=l*e8LIJ?t+oAE$*&d!4_nz}TTYq@S+(-R;FTHT;P4 za&vPXdtdhJ>Vb;XORb}XtM(%1fpOe*lf|3M?fww-tV?Pi2%&^9Y!cCys306b)CvkA z;Q@Ct!3|Ln4yz!;oCwqk2*qi_a6}M+Fi=2&2f~muglJ!40!I z3c~?$Ap_xVUV{QeD08&$3gPCYSPhDpIm|8G>jbpu!7|=W)8u=|G=`O0W3-^tCZfmU z>?yj{R^*$T?dLCF{`xo9`>mOyI*wMyhjIO(c{S^A=6)aJAO5_*|M$*{X0P{#tE%^T z{KMSlZ^!<>9rf?;eE%B0mmM8n7>H0&papf#*^wv$APBT$ltPsh@OHQPfC_XJB|#{~ z0~v&ykRl>LA_Yj&cV~;m^LL*<|Ir`*#h?AxWii%uFGK(6`MZ>9cUMg$vKp!fkeAzU zFAlps`!t2EH#rP&gbG8c3I@y&00b6-s-o&9P$)nMSZe`b zCS-{an3K{Hun1_%eU}!iRFjNu?q#auIPEmA^Xj~Nw9!29X4*-)-R=knNu(qe2vYBB z%9hXE8*W78oZHoA#P`2ymjSAZnSIZoALb_ytLpEW{zHpz_q_L_`#RyFBemPx)7_i? z@u5tpLOq6dPf1Iys!9Y^+DT;Qsv?wXg`@`)1#|(D3ffoYPLY;R1ETFf5JW(T^uPPx z{>LA^_rY-XINtrefBaAXBfb2U1p9OXIuR$k>$1NV$$9noaCdDL6Lyo0tP!#v$I|Bx z(nT#1m6{`hiEt1Gm2e;`DFMJbM0h|XU^PIXwn&Vms1tJvpU58O5P?)g3y27FCWSS} zmxeo01kB+<6|jX>gn$W(gou<WFzeJv$eRkQgH(aQHKN!^NwfD$Ivs;Wc;olr)Y zn-kf>MVn8C2;C7bZZ&9xST#*qG}oAf*-?lbW+5)Bv_x8S)+M$P&}r z2N4xgQet?}BWQ?7s?1u=yjrK);GmWyG=EcyN04xLC%sO6)?v|Gt&4S9Ef$-Tr|I{9 z_}eyQ0Ws`(MS4agVg%pV}v~1pw)+P_^NdPA)5+Z0HSGzsJ zMD9a)GocV+gsIXj$PjTe2lOG}^U&xY-tw^O{T}xE@M_C{9+uI^=Yin^VFHZlL*B39uO9XjavvyanUkm-^S6`+@HH3y(w!(`1|6s6VRW?>~% z-3@e_I7~u8ucd~=#=6_>Z?|_hhs*u#ZAvRq=}sQ;(b;hJc(v>%q<-N;m%AZB0EzR00C7s^MLS(nKn4JneTly{18aJ zzxwbTcvu*Gr~E}j2O3J)z_<`?sct)|{-IK@fZq}=_ z$ET~|{QS|$YS}$`{A9g8Tc4bsoaCWDS>#Ugre7||syPQTC8y=1W$IbXhsTctu^d)j zM~4`8hw0Ftt-OR<&5N`fZ*C4^x7%sj`-CKZd37P!4}AyiRE$>9Ef{-eN@BI_KoLz0 zB8moMoEo%Cl9Hm1AqhrJ8s;GfPz3`tXsm7k;P41o1we|V&VBOg<_H^E!wJF=2+0kU zFEvEP#$r|}Eg68!dAWcP2H@<(>LjE`M3_5-xz?)Uq7=-ML)k*q zEJOgWLRCgJg-Sa%Jj6XH+1ymb2zmraQGz8LZXhKEBDqx&HH5@e%5-~uclG*eJXo<3 z%5L>&aq?u?tX6#*7AIXTSAAX#-KK+TgeL?v1cXN%L481oX#GAj3lX-ml7yKBLP$5K zvSH-j{G8x?M6>`xb5~*5Y_Q+Md~j@R-TQ{9AifXwH{kL?mOlf1?uHpTaaFo|mjKP1 z6`1?YVmLcJ?UpC&e(G0ej~_kSEc5y4x?5}>ot@{Qr}k%?ldjicSS}Z*%Vo|w4BenT zC9Ng(?aTJiu<&4Q(9`GvFpy4ewui^-E)m-swLc?ul1>7yo%F(bC^1>B#Q-~eTYfogSSgj?tgA(3IFQiM{4Vo~qE?=XOtAfl)Z*%S#kiLFd!r%zcs>V6z4tN~9>I5|r0g_&w!r5(RCd=L`0GuQkoAz@4QZBzaRJ8sACX)9!Licn!1JW-+kP@ zdOiK$|C@h~yk0M~%gdo#Ac15SUFLp}+V!dPl64t==(|3vuGgn$k5WH`M1W(K2z5r+ zf@zmG0BE3eWjBh_%_vDkz3kI+Vbe{W4%6;{DpM`R+(M$%Y1#@qxKjuv1>qqoBB9-& zDN_L!h%!=$8ZCqr^(e~BP)C?oAV9CqfCW`@hkyh;s#DzxK(m^1Z?%%iy$-{&c181| zjtBEF2yI^j9%(AOvOm;t?U2xQnsPrRNk&CfgpzTvl0+{pw`Ntf4)#p!uU3lb@1I@g;gXOEtqzqwrvG1ZzhQFAeOE~Z17rV$WD7!;&X%&oOl z+m|mQ4e=!z2vM2aL+$W0Z`fkP(Odh_=|Dty&Z*V{7y&R5q`HJrv$70br(K^k7DLzN zv|2Bg>yshn_2wk?-O0)6>0;S0R_oP}I$5nwm&?Us$m`XK=CoR^mI=dh(=FD0-%-0X zoRHZ=!o#WNEib_60Rt)kN6XdFY`tA*7^xpkz5Q%_0%>qw$Qg8krKl|BdUw(C643YA%?z@x{!&UQUDNk3+cQ>c& zI>M$-H!0cU)01cKc!F@VaxWoN6#_ZKtw20yTUa$oH7sgT$u3kCx6-9m9S_V=#;Hst z9EbhBlv0aXOJb&?I=6L1>28`b0F|Js=)z(r`2+wYMBv(6N<+YWN~yP~R1_;JNxTPa zDm6SLd4<**V5!wa)qJw5Zj)8yZs@w)FM8Em?ebwPrQA-nhOX#!M5%@Q?VWqc{jy83 z>ifRmq@*b$g2Kq!SpY2B4P_jmAiOdp$?9~I7fXsPHz&DYu1_|phe}mS?w5}rKk78~ z$$$9K2en3**bV1EF223Jy&3o8#m&w2-OcUw&E3wfZ?|5%-M$2&5-qJmn9m?gYnIcj zs%nHcNEUE+Z*A;qPK1g>L?}a7ht=uOEk)61u9v#(`@HH;*Qc9Bw_2{&=TA06>K13q zRlnYxtUd54%@{K zf5M;s(^_ArH~-n97AZ1TnanUwH`|GU>XtPvmNGqwB&qt8%YN_ULL^mRpPX4;TiuBE z617gCgp~ss0jt%=?WBF@VPU4-%3%VCYGGAThaoUcW4P@PletgRom;p=NhU&afL?2b zVH`ygBt$e~jDW`lvm(MGavmJmv5IIQN?6uZf_)yQ@utQ!nVH)(9VU+~`7qWRWLWV7 zAS!A!4<_NTc)VJzYK#UKQcVdl6VmW#eiLpKhq%|apqs>sO@4l9~1 zQz->et(3*GU)g(orF30R=(|1*X_@+**WEG=eSY`JyJbKA;qU%lsT09r$XT<9y5zCc z!)|xAy}G`>d2@03&Fk0Se0%xo;^NKAuisqXUR~U74*{mP%)Yr@T0{g9IZ?#>t`FF9 zd9qwcNH++cJbl!!P8W;K$?0mjh~;9nSwHPFmqY4@e%&umA3y1mrmj0bJ(aW=`Yt4; zJ}DKl(5{DF;sJ9;V{ptFOEXlqcIs^Cd}!AAZd}KA9pL`XXyk|)Rsj+5 zzy|_A@&^981E^(E)wA;_i`80lw=*-qBFNHPS#ZK1{J`J+kK-W7H~hR|yezD&4!+JTa*2_+l42xx# zH$x|BNMM)q!jMEIAVIarAj09H){yG*!0`AWe7Ay~fJN)ILvU&W* zrT`Am$MNO*u{}NOPn5UCj8G2H8}(n*OLp}R3W_LXHj))G^7J&e;>Oex!GM0hdNMwp1ul#=f~pj1t< z-|aeG`Q($|bp0?+MFlD6(2Upv5Y?$1$gUWK;$b!wbbWP(g_~>A@VG4n)noz{ojGA- z3NIumX}w&%_x{uK_33hRg4B~88gHu9mK-45tV1>tu6s`sm4Nt?!lJ z`GY_F)5|xnUwr%Gt8c#i_*b92x~kuP{l&Q5Pvy3F?(%SYlHYm$&L95KpM3biv(vMu ztIc^zX;_|geXk<9?@2-G0}SaR=#U6?z=O3Jr_F}_z|P|>+ zSh0x2mbQ1%n@!NF;}57eNUg}ZwI z+`Ee~T&xxnWnY5s!KoGirJ6zR_7@{)7Gs$Tu`BgZZK~tpuq)PDiP6XrlC*>?#Xxf_ z#StWH$1IMjmPA#=!xS#kF)E=E4450q6bO;_>eT6Dt-Uf_VI>%)l=h_?pdlq-k~0WN zA(`~WkRP8tU7Van9!O%E07R)EP)7*eJ*+wVgDt2dXo+il(L54+p->Ddo{_}f4Ey+3;L&b!_Eaiq@KAzpfQEn|-szvloS zGn@l}M?-J6-Z0fT60h#_pJ=r*9=P3HziU=#Qcjp|zukUw!JFOdPyRw*eDfTq`oH?4 zz=691UR>kp@1i~j6fnfrpIoJ{^epw&g8~WlXoP3D$G9Igqoiti(e+t!x~uz%b-g>? z?Xg*V8Al69v~2xgPNfEGW3aiyVlPwVJeVegX-YS@+uV1x?nJcIQmYlOrA%a^sQV<6 zJXj0}8>gLU(v;kcISHhid$@&J=zcm>>?ZfSDy5b~#5nH5S*?akPC8DN0v0C;4+6Cs zg%rt>Np)7$q-rv^lo94BbtFA30h)6uK@=6OrCJnH1A|Zna5s8L9vW>H;j{onRO-=L zsvv=?adNWB{TaF?1TcpR%%~FX&;*3!6pe4v8iGQgz`&a5`_K-OLP!)BK|kcae{}lj z?Ag<4``gpFAB*2^x7(XH)I2N}Cuf`Pl<NuV6Fnz?p)Yxjr;IaRz( zupTB_^WlPr8CV)#Z@;>^K3soWZw}jUK1<*3mo*LJ>mNOReE0HYy1j~yB{KY zB!dY;QJ>hq_aCnQZ~y!$`y8l{n7e=^8!ye34n@+T>(@>%0kg83_S?hlR5vc2dG)C{ zBm!=3V(vAiyx;Bx1f5{DT}tW!6m>8A>0oXUSPc&pFIG(w!>4hYYPd0iv}poDa&P;+ zu-e{5$^e-%!l*sz z5@y9U4;hJ?#HUVWj2u>3c8N+Qy-)@RBoID1bFIZa#H)}w=Ky^gLr~qiZn;`?j~_kV ztj{FLcM|7$l;Aic0k9j0xmO#}jIG5&XBa%-!3c;385B!^uDW5_du&QMH=oK6ru_~Q zk}__2Vz5>&xyC zcdstLdhz-14Nu4Y)q1tKJ&ckU{^K9W|My?&U%iKA zsZZlHDPazmJ}?C_j^^PJGHq`hQw^yM3naoLsym877(NC$PIo0N4}GaHs+;Y{(X1de zNWd8os0tx%)QF;z+DR?YK#NKMRJ4R=Am=RM5T%F;7@(>MZlWS}b5Me4inoIii(2g}V`7K_&EhK~?|2Ly9O6lo)XAql~l zJGa^lm*MlgL~F`grC3M~=Ejc;arC`fUG!dT0u}XW( ztO%PqJ0jo_UNUc~5JCcuhQ3-e-5}JbJzKIb5;drG?k!7J*-2hk_H~j6^{pcWek^la z9qh-d0{17w@igGk4el#x0-?C4QwP%Pn=7lBZV!FGSoe=EcXu)F#52dmlhYN}F1JH2 zE`Rgu>CIKV|1R_^yn6#|@a{@~u=>&0w}~kCw2|h5B0LVqSxm#w>(J$sZhti$CVPD| z<`vjgHU>gFu-x4&B9bN#w}@JcN{T?1?)ql0oib#a4z6P@VK9W7heZUv6bo2&3!sKE zU{NPCkyQPl?2t5M7$+wfZu{{7k**uOhKSV0@T4SBh&WvYq?A(oE|VcyVQz3u6iS~c zA*wpXD$ugQIi1lq#{xw;%+EzZV|4MEoK1TZ465hCKS{-eSH4p z{B-^JDf&gk1O&ad>0sPjh4YvwJ75tBh#Bvu1`wh#(-@R7(JG-dr%yo*X|P2g4Qw=W zCdqfQsWpm_b`MLWYl&N0S*V?;VwW}>)E$i zD}!i2+3E$afF#`IG@7Pb#f$-s_S(R=Zy(VHS07mX%)vyXI2yIgn|yXv*r{=@(Gucl94UcLJE>H1Xe_V(#7@u&X`0C2!N|6uyl z|M{aof3;-UQ^G?i!MWCO_d3Zq?v{B-G<){JcHGre_S>nO%H4jaJ=`4%LLx|)0IN@& zs%mybfmk`HVqKYR&$rLm)v&|5R{yPVWJ+iEI~z^Ku}e9 zL|D!_BC30*B$G!Tl7|;7V(v_-!5d{dgqx7HgsLDWGJGnMa_+jWAE<~nLIi{mf#`c! zw4;`7h=&Xp&V!#VIbcXowPh5}j_vO?#45ca2oG9;f|8sBGqh4#jVeqIAX4vG7_}Lm zV~s!r8*iqTLeBW5EO%kQreVkf{r0 zj(`Q-=oW8#S#b|~21xjQZgcd6xk~2S1WAa-YJ@DJ{LxRadV;zJCLA_+{$#c67OIFwAgdyDcY(TjkgH)$cHKI9 zES|;>@zqOT-)YL;rHR6%?VT4JBSa*Z#$`7PiDH$)>b0;&DG>}34q-Y>V+b4qh*Q{Q zmpE)ks)Q}WWwM$6`i8iqk&VZoqf#IqRl&YXWonZK z9&Kn222Cn*cYS%-UN5F+7&^E#O^tbG4IYv}h5+sm&}vW_HD)NnBmyoj!n6{Y6V4n! zQc@DFNTYt#0G-K#2_k{SsLT=(E`5!KA;TMiHyXwm^TZp#8TDy%N-Ye#&4JdMV>BRh zX4B#b&2-I51x`5z@Mg^(F?Yk*__qOugFH5}zS9w#lN`2J(SXzk6AE#h0B^z(O&(%) z0Fpq8phZR#4hZgStOAVV3jS!hc~R~(=d;xH!+QLkkN7A57RtX3l$H!*^@ArTAD*-O zs+JHxGRTQAQj3rK@lf4T-!EeTQljs!QW_SU$4{6Uf!J4viRSQH%cT9VuT!p-NJ&%i z(lY2krMMdzj0hRJX*y(0=HkgE0`AN8GOPlrT3Mw8AZeOvSu6$ws(aTD5k4NT_NtO& zSrV$bN*9by5&#h~llIj~l9n>CeYY~Cav*tedwp?rxjwn=_gFmQXrJXy?YMTzhJohsD!+Zd+k$&X9 z4B-*;KO&!PrjWvW?`R!`lyzB)Dcku{y^Ir>+Hh$K1k|I8 zO?dC`5AXe(ce~-2)rtTP6{?}Z+J|X8jCaMhA%kY!oaBg;vxlpV)U?xdxa56T~EzlyJ8|70uGd8eI?v(P4_3r1xmmuLq*y{6G)Y zB$;P9;Z;^OMb z*=4slVe0PDbuikrr;B|1dD*s(e`r{>yVw$(UZ3bxsY?*;Mrt`B?<$Z509 zFSXiS*UG>77x+;#t zYH71x4?|B$hvJ9vIu4^!JaTwRDrFj{QYl`FOl9;siEpN`D4x4SXf69JIlM~Wxl2l% z%0v;s#X%pU?@(>Xxr(D2B?BRVS)wSZ5C;3HYagt9gvY3gMHRS!g&^=Z+Hz5u*f2B&Pr_Qt1#kxDW;cq-4{6(I*5W8c#MrYQKO=9~N0)B}A;2uHTruz}aOB>+%Y! zfC-e$6lNH`%l$H#H)8HpbpSMVL&Zd!NG(jY-jrQQI;7k)v6GxsBzKN|mvx**7juSmftrV2Qq3g4`YocTUJTwD3 zpX?+k0SzFK0#b>jC8UTJ?!9SSG`J(&D9NXw?PQv`IPu(a1`P-y20B-g29Z&wTa=1Y zV6~yF&^%AsY6o`4&e63Yy$FqVG&J;vZ%z8XNB~1H*UimtTPE{&TmM^p@~HSWCpmEh zyW;3>Z;zJa?3?f{*S`h(qaVzjk(pW~GvSV;rw~|F&p8fzg(snErh5-)gj>;mF>*kD z7kLAm1Nm4301K zM-$L6ch6ntktFxd0hE{{m$n))TBQg?aN!6uY2vn6CGKtWngJ_^L4nb{Aw>Akp9}13RB$k=K){v@@ z@6vd_%jP^@ovr@?;jLYrf6oveTfcO^CHKeMnuIg<*-X88sL)&BKf0?Um;fwKR(5-< zjwI@JqzbHzOkz501N&g22od8nCeRqU+)oN0y)esX}#$x7SDQSeUN@F_!bhnfjqKPCm zBcLK-rnz%7Xlp_vGle+>n!AV$_6}{0)d!`gAQ;Cq7*IoU>9orU6zmE0;s^_Gl&U~2 zjF3`d7?3;HwId6x@ez!J=PXgFdqzcdI?*&+!x@2UDg~;cBee!PLl443*m$?jxhplB z?JWNAUD)P$`FrWmk@)D1E_xEf6Tg;)o@u#(YIMLX16f`V}Y_y~Kwa|$m zJ-JJA8cC7uwB4vA#*&h14R_CjP2*K;KfHc9{_BX#{~Z7O{|NaEJPy^p{&INo!{PlW zP=y63kRvD?_Y*n{Q5>sDL_h^KU;(iidWX5i^{bbk{MFB2eDg)E<6(Ozsp~a8AAZnB zq#+Ic5+p+*Zq|TT zTnI=NcM~C?5f4DGp6O71SA5DFyP0IX(r>v9fHnxtCQUL!orBCJH6rfEDJ#&IuX z->K%I&zkB|yA7I@rL_^zZXRE5s6~_8XnJe_8Y}}G!~f9@$Ogj$8m@snto8O2)y^V^{Q9d5_5V;eYPTFvem5uDTd2#_8^7guffP{phFQ;G5bh^i9(ut8=JZ3d!ZCTj_lmdKQXD(J1e!|j+fp16$LJt1=ggjp zkhx}<(V^xu*3?!~PAXXkdWm6JuktkYH5!{>g${uBKGp4JaW>t(&ixWUS6sZn$@@Sc z^?3b@x?X5~f~>F#N{b^=jqOYb$K1vM0NAW`idjm;+hmlF`@5T0-+c9AI!r(j6)#qN z3KhW3qZ9+Yp}i56O$?P0pu2Gt9Q#yn#sCCh*(P_bh^t@_bCa zO+DFu&Jqa_W`>8T9z6`u)MOAj2P>ZeVMx>}B2(GE{^rZiKKu0BuisoL$2 zb8_k2?4|R}!F9&+ea_Q_H z8F_iMK?zV`l3cqgUJyZ>q>gQnB_t`TLxI$g^-5(@YGc1OCF4G*1jG+8(ndhkZX?mXYism;Sa3q=A5=uJfKJfflesqbq zlLT|GtaX6j4k#q_!^tvr*rq&m2G}8LD6q~LY`>Jjk&9}LX>YD6MR&?K{{|=j7#PuA z$`^le_rs4)`3ERAzaJ}&R|&Uh;)lmx;M*Y`&Oj|lHYHB?o2$G1?Oh;1FBPIWFc@^b zS<13oE)qp?-}X+)r{Z(wM`7#RCJ$@LNi><;)|GD(q9Qm-lZ87}yjDqx;H;fJqbsxN zAJI1+JwajB-9=?SU78HToM7mTFc400?IemwhFg<8(Xc?}Od?=QsU0FrfPfxgr~(Eck)cUqq)n)WQvoMU zoyY;qF4>tuMkI@FK7}z$zrH;d9vlU4$00GNcL3a*e#)HkH$aID4?R9mYt*DUC_Fez zVy@09^tXrR+XKeadc{Xio-TO)=F8Vf)j6ivE)zRRi>^P(T}&nFZW208d#NvXn0l}v zfH$AX%S*oZ{@Ym_C|JXfb6m%l002HgyY|7oebXLLg12K8=#DAQ=}G?1E95E>Da$JbxK zERInAwEKf)zgjHU5T(!dEviji7jBFq6rWG|*&1X<7enYCsij5^nPmbWa3F=&{_sJ( zoMT~7+E_fTz{>3TLf5QeZ4m>bO4-7Tt9W+;bO9O{0dXc}q8w-w!cYs*#!QkbLptX| zXa+@Sgft6n8eHF*AG^#2+rVf_$G3rz7gKIdVt6bKj6D{ zhX9d2`oYrztGaL?z5xav$@$kU3xyVA3XmNzn)s)$s6eQGGBy1XAZZ$3RK< zNe=G?lcmjs1WBmEYCuG2A(SLxZf!;-EtZcKtIhW2RgF^XK0*vcXwFj1uP$zW_3N(| z!^yB%YaVibIddhtsF!}G)XOp10pbuP(ux-s#0B)l7n4P z83IU9BE)AAI=&@Ae7BT^&vPcnBX6#Gcoft>ZYd$#Xw5t&&>H3~?RlH<+~-B@`2w2q zaFSSa(nWvhCPSZd#8BLAUnzaJbl|4cp~}$vbU3geu5O__lqK{je4}kaMry;IZ6;Kk z$|HF6Bt=8|+#musK&{mM;r8P8rkVv=eWLcdTrJior<>u~`|m85OG(`?JiAuxJgDIXM7~wo9Ix4hlk`o z<`3Q}3~%cKGR@qBXnaTkT~fE`PoF+{KHiK1eev~Y)hV!~IdUa5iL1oL#Wx>+)~(Nn z-^zoo*FfJ=L_+4GduCu(VLHyYDq(T7jAL1O#L5v3>C?Gs;}QmdR_A34M3eb#(RfA* zK#;DzG1pi`96O725LBaz^i{DZz%Zd3NYs0WgebD2I=sThC=(95piB2C@{+n}WUOEx zOdb>@Z{$SRxF=J*O@od({QX;N5$f2=YBE2wHYuB|x4+H&IVXV;?GR{>$9O9aA^Ly( zPygAf8@wE$fA-Ob zKYa4+ea%@A5S^)5tq0ha$}sK~k3|Ic65A?3QzAwq=^o2jXG-A#w5otJn@ZE1`O92) zMl{Ltc?r+4Af8JIQ8|8=P3U-*;l?q$Bq^F&U7j^9hNQV)EQ^CuP*=OR4COu>}KvpJSU0jN`iEn~Vd#`de&y}V`Yo>x_m__?;_ome9txe@_ljrr{Q1u~ zbFhz%H3`TJ2Zg48```WhuRj0k=Ji*vZZBkUqSE)}%Hb(o1(REs#3c(#aaz?*eSCGp zw1)g^9F)@-;bn1Bx>JcZ*cf7!QBXvpAOhyWpx5L4UTa+VoRm1n?cvSqH)auCG9c%L zWIsK9{N(YIC(oazB-&)}kM&KsgF#XE%9i}GttP^pnY7PI6^JG{!(*mSNSMtTd;}x_ z33o&#XZ$$=RG~k3Ou**@hY>LYO|1vuv$9Meyw-*l%^TSwA|Oc@n-j@7FPHB;di?6@ z)!ohE;`NueyK%R>w2HBEH|;RhZ@&8S@JO`0z>_z1^LuG^4ry~WipKx<3QZ0I=~#8O zJqc}4Dunfj_c;Q@LkRAz7Ra1h&m@7CFy)!kN(m|uB1YDTM7m-EoPfl{C~UiJ0MtFo zRa}4N*S{7VkUNCM{!N*7Ww)(|n?P3%w-xTU7v16{t)5Fh$NIU5G7Z|DVDU`yCPbVI zs04Dv+~0^e_K@R2<}QD$be?OVHZC@2M-QO8`_u9sU7BlfM~Yy2{Lzm$Cnvx8ReJO4 z>r{7ky&F+N^Elq5)Mq3F4)w4|!<76Y(i7GG^~Ln(KgZAh5|^<%$X?})60tH`o7w?F zqi}Gsi2l8V$RDjR~n_$z;?d!{n7hRvKgOYR3U6(g!C-1)Z-e!F+(m{YG zGbyc=U~NMeB{|$(=p>QkzTK#;-y9wk#ZiyHwb3aEFUL@U)>uFjpmsLq+q`V-zATOq zQ8y2-R3)3)X+)D-^k|JzK{((Rt$J=X36LOMP*paY^X1uQ+|}F1XIFRo?e6B{>f6Kq zs#-rze70Ji9A3$r>vH`ofAopI|3^6eeZxREKp4hKh?CjCKo{_1XUB;mVQ)3^8x(Y3 zM~25t2xjAC(vJ*<*2rtE5(c8SK^D*gNw{MK!=jETqxT#@}F>ONnKnixC z1v(Fa5-tHY;(6;hf5!ptI|)aY5${1&yd@3sxHYf^u|^S1v3@k<^k{qg{M#R0MST3p zzj zht`hpwh9tv&}@g>Z@>B4EDu@6I!U5Ptj|u)&)1u?B~_)%45CY|BLgViSS!rJj1klj zu%VgKcG@*q4Dz6EZUf_Sg~CYo8*oX0V#>D>CtsVwR&>8dG5Hqy{?Df+HGH6ZC~#%E`HG2W4*11sT|&H zUwn32@A}_)9E%?SiLDqkhu4t7(T0$mfWQcwJJ>NdiH`&5^FEu9G;dBgj<3Y=bC{XQ zFvd(0pcg?Q0yw}*l>InPbw63TDfLh-a?+uvC{ZWhUSWTsxd#|i&5M;RPUB_^mjMd9^J-qYs$`X9ljU*C)3HKE5I2JOIT7}k>L!cF^C0nD? zicgG4(>U#>H?J>qPHn4=)tZORYV*$f?|*pu9;Z5vwK8V!>3ymrg5y;Uatyp_!D9tVej-ey>g+Cw5z7wqOa zybSt;T3ZqVL{y`aRP(B-Z}b#sB-Km~tF=$#`Lp-Rc(DDuce|VY%b!2K{-x~7-Q9kB z_jafvn zIcm*kXK6LCR!n2uT~Z{;qHGUkEX)~oqPR#0=d`~=i2E0Q{mJzgd9iu7Uq0!d|F$k4 zas46kxvVyThUDM`cEK)?8sj-YH}bwFzF)&e67!~^20b19B!|#Z|}BQ=~h!p#>hi{_U_}SAN&Bz6VrtwTfnJJQi&|4nj|EN zR1*Wt!)3M%J!(Np05TUF4F}aAkH3w%n}#ErJX6I*0+}%{krJkWIMFCH;)S+{*N_}Z zE7uW8I0;&7Ad?451{`7RwS5B`K$FezdoagHk$wnGX>;m$y4v6D{WpI7W-4#)Zm%!j z+)d-?*Pl4XN2$uQf4p41+fmW2XBBiLiG$P;0qcetE2m(lD747fC?GA3n>!2lJ?-Q0 zcC(iT2Su3EYXrQGHtqKN+i$-5o4*iB>9k1W) zcGIg*F8cum|7E{<)Gf}}AN}F;pZ>enzbD-ziiLvkVApg=B2vAt zEG;clN~ky2uQ!iY3Cn%Gi>NULRx;}_z9k9VgStnxyYRPZ8U%Ds`;Wi)bn?QO%*?c7 zH!L4LdFO|}%k|l$8;6D~Fv}l+jOc=+GXn{!GG&I-*b>}(vdBF6VD$($3E)UGjzMX& zjKaChWrzkeknVde0PVrKDu7D}SM(B0#@?X9aHK}7LO7U0oe{x~ut@nkjh-e}aOATC z1hwHu)Ri2pT)wL1u)V#kyK%S2un`&I~t*5~>t91(Ckntt11jwmH+DTi9@u-}c_yUTB1eDcMMm%se=$Cqzj zS~fgjCe|`Dc&p!O) zf7+cqPn$;^o<_f57}%2rN&w0Ngf>(R^hhCs5Ck1Uolgdp5UGMf7@_oubxhW0amTP+ zJ^pZYd9hr*|Kaca^pjuyn<#bck!#Hs!C*B=AMo2cMH$~&pXKG?K2efQf&GYc9{CR6 zZD-$y-0#dgv?U~Uyxo2E^4r6Bw>QAYelz4@d2;e}vpMn91vnF)-acUKUx;A=8kpF~ zP7(|YYRoH=k6BnJM{&NGd*DsK5rMc5%gr3cA)Hrl#}RysBRMo2(3y)?K@CWR1V9>q zXe)_grm^4Aypa2CRl3 zB7pFK!+F^6_lN88Fui&G?e1!Pefi?e)x|hkulA!K{NV2H?y$d{1b27WhwZnQ7sLMM z?5FSkX;Mz^)wTq>)$*_}`|Y+HmfC3=PVz8Bc)&1W(t|Ef3d47IK9yR{Dd>jo(bIhL zSZ^<)Ur;P9ENQAEcl+zmAjX%U|Lo0+kDq+-!zb_mX#K(O=d+KGq3X zZol{%ydpw#JpHI2hSl=%(@r;s+t;xj58wXJ`|k8riM!$S`Hz44(?9qpi^Y4xVzW0` zDPjlLh0NX5hG8`YD~sl|;|*Yd_;{d-)iUmGQm6avIF2{D>q{wj*W=ao#m&{5+p9Oz zu2f7)85Y{7Q_+5NvS2*g*DBLt)%$6l9-XgF*V$uV_7x6e4QR@#8&XbLSRGNTmGMx^ zUfm5nGgt-;9b~$@yIa3-BceU*Llao%)((0t{@22rqg1h~`qJWpV%k}e{>zBVc z`|2;xpS}z2`_&J+(GedIVC-HHkwKq0FK3-4QNtrLV9 zKR))ref~Lf&*yv209m`;+Zg!UsnM7vT|HXe5FRtO+6X$q#1=APO;s)cLlT731qpNn zOoq1F=`9;uV%|7+WXFRZL80Jqeeub^o(>no<3+9$R2ZpD)Bf`Ew!G$8nAUf9yIO8m zi!&7b@?ZVecQ;pm^2h(l=IQ&(licziiOP8pW(WFB+++4rz`&6fT zb9=j9EWUmD<@RpuhSh$1clqYk-OU?-icSW}CLO_i(sfVsu*eC3pRUiUT`#6L?=S4+ z*(tMBt3Y*zh`Lh}7OPDeZ%ss*OBoM$*SYI-=xG*p&l;K?Dc3`l^GA8;>VDi$m(y6g zv!}s6uNP^3X862JdmO-oTHQHP_TzMW@VnjJtCRK98+?m&H>}S$&wjG};2-FdpN4Ki zQnU@#q2fDO4KtL|+LS>(LLiFVkibZD2b+TFPI5gve_Rgu#qPS#`LO85&Qo5FWygdx z`u4CpO^fL;)zkG@VmfG2xD;Of-;lFvrPSMClbZt_I59TWxLgFF!BYDT;k#8>_DG~SOO3bfW z;%KPeI=V3vNGkHYoSp@tEyeD90!mDwWV2YK*{Hp=bX`D+^Sx$ z-WxRQ;qqlYjOGWQxZ9eW_0+)K^)?c`1D^Ic>Gk7Z|M_3${O|mG|C{0L1Een4m=4Y+ z86Aa^p^0RKvDVkGzFqf&tcTm{Z%1e;(~CE+o}N8>{mq-JyK9pB!+|a#+EGLD(5c9> z>-+WQ>0%gG>qntj4H>AKp7+2*$ zxZd4-y}fy}dimwqZ~ddiPyW||6G5RJSb?&2w|O*0gd!oWJFJkIy6>f=fChuPlYK>` zVX=Pv6ldp8w!8_o@%99Eha?zf@|@#fabV6!7=lV{fH?NHKHj8z9|` zmT~+>Kfk%VT&zx$NS0o+!qaBGalv}ITCLZ4dAeK=%Wh!aEc(6;Sa`kW?rX0%3Neoo zrn#rHL+6NbzcahZqH(uB++Oc*UP|Pb7vC-(KTZ9)bh%&kWi;)jAC|k_Em()sW$xD! z?xXs20GFkPS*3ZOrTWZ$EXCaJhGn-qSW0(+Ye7_j?XRuu_IIzImFeVn{(a{XW>!on zVMSD#Qa~F}jPNLvS3hibyYZT3pPVTY#SM~)q+RWMzW@A#FYB+JCufg3JLK`^RYF(7 zQ!ObiHNhMceIHZbb*GCpsuK2~AMsHAf=3Ix??qR=diCiq{(66V1?I`CiU2uktWF-C zJ$)bD;Io|Sg9_LmT$p#C5oCx(1dtlb_nt~Sd%|1yJ5mIW9P#7TW2*MO7ys6M-qznC zu#m*S+?70Ldj#Qelm_I?lWuRjI-pG`DrP}&Mk|^b;h;jLTRugKG<0csUKi*2_VW70 zCn-{<$*-hnkd$(D1rPhF6?5-D!A*U{Px>}tkP5rP~u1{7&PQz-^pLC0j zrBXP*4w+Vyv;h^t;=7eOKlr=NWCv&C?7=(izVs*ib?7U4-GB2A?l{Z{0#TIJODxi=(f8rBcXfO~HD zY$tO%l&9iX)xyo@d+0=to5K!K4oU?te$$XpiEM2f5SRK0G0yd8Anw904|wG9HB{S_ck!vss?xx;^Z-hiYuf8LMsqiJbeS3g5}y?)I<$pGl|g zga07dZ?9iozW(Ob>sQ;`@i6Wnz8U)6-SsD*eXfG5%U1>t0!CFeqnJd%MAk5AwEX!+=g=<@XGri^iU@k(1we! zl>K-=Jr#(>vd>9Nt(u2wC3{HM?{>F2_my|AKlvY0mh<2K5LuC0`15es;c9z(yT7{` zZ(be7-C=*1rPCyflVvg_fW~C0ODKR+^K$dOXmJ=B}~dLef68){LRN2jMP;xA{vxp1u4#+JnfeK9x42| zIpm?mV&psw`B!f7l zHKjZ%M73$^&n>6QVCSGwq^sodPk`dn3zm#MtssHtB~G1(M4 z0D6#YqRSX3yZFuZ-~6|yM(^LbxVn1r#c#g3xV(A&a#s(}A3vJN>${5xBci(Y-LTZq z#K$KmdDXu<>7G9S@PiLNSZ+==ZF0X75tS5343B7=cdLrFC0kZK=+oVs-Q|m}PcnGw zJAklBSi4T^=mKJQ>rs+u36nnh(=)w%!)X#pA@%O%OHkkY@$YrR;8r6J!eUkPu-xrS zjV?1s)UYbOPup5Y)`)%xCP{**?m|r+B9f+3tz~B8bU?VOz53$kryu>XEPfxXUT&w| z&HnE7{$_U=598G}SgV<;uFs#GKYlWtohLzYV7k}{=J{_7ok^_k>R(EBz z6Mg5y_pLvVnOXE8Y=6&W?;pGwx*QoVM>XJCv-NFsKfWxvr-ppj0r=eqkGE&VLnjFn zs?V%>Y1aFlmlUoLZyTw-2q@ZZ0Wb;?5r!xbae_<{6Hx-n#PtvUupVAqUp&5h_38fb zx+4@Gy6A_zIy)P;`)MpXI))e)I`mmIg^H?<`|HDJ|LSo0Lf`$<;=`LSKmPi1Hyw75 zpFT?|@AsF7X<`(hv+3~o@%ef&tQY*?>DlA=-`P%Pk#px=7H1K^5%g|muEEZ2437w} z#_4ddh*ImJ?(V+*v*qR0)90s&?p6WMnWYp7WSfYoYOsn~1gmy^%5^d1X*}%qhc5So zUB39@=l{R|_P74vPnIW7szF7=$6!~HuW#-|&bv-)J(&4gA06_AnK?)gk`x4}DS_6` zPqS)nWtwb}hE#a>>iU~soo{{+bvoQ#?svO!w;#*sUUboicU{Eh3{U>xKRDZM57#eVe)+RkUw?Xc{q>`yn!4fi9HNrOJPhvA_d;N~UX^lp zDEn!@Q;%u-YR%2r>iKHA;&}DsosTwW&r;HhR|hLoH!R%Cd+$Ac`t1CCJ*eKuq3Iwo(?a6^U3wa%OC&lpPs(+ zBTBZzfzHKhdDxE*x|uF|yoqW%k)RPfwPcM}w~8%@|_v`XDv`j#S0Z12^Vu)|()K0-xCX2f zskInj^>F(5{b6%f=fwS3(0(s(iSJqGQTqK}l2U>(OFaa>3qWan=QOxSnci~v9{iRM zyy5;h@-};`#{rAk=R|AbUdkKXeLWq%+3s#_x2--QdWpkS?~*16RFsm)==&2~6s9C0 zpsOU!15=-d<$C?wt7qp=zy0vruRe)s++MtP2bRk|FT7Tm(IYLg{l2W1%6fPG#!-@Lvi(nf>;0enMP|`yJRwN*K0Kw^S zn#SlSEM&7vi+oaTq_`yf{xkjLv!CU9@wngedWYgg!n{PSnW;De&-1!>8_jLJxyZdB zSFh;0#cHwaP4=Z&$CG}wy&YrnPk;Vb9|G$~?~>inV|)8X(|~ZKPKI|XzTM+`fABVJ zS3;6%%7P}}6mZCXvOX)6De_?|42)tvPTp+{3*=KB4jMI0=cpC*r5&tHgdh!&&c`vS zjcOyCaFQr;4l1UpTW&UIA3lFN-d?=A-J6A5)IO)-(c@Tln~$F6^%AS~e%kL|AEulA zBgtk*i+mV3XV$H2y}kLxFYm4|k7^g8it1*03>gg2S_cM@tKGFAPMvr{< z@8s#TF>@Zo6u%e2ds{OcG5Pz;4@N~|?i|nV5J%@Y79@rMqfG;AsBUw8IbD2teeuQq z=IiP9n|&RV2;BPIhkDodSrZ-MiHU-$s&scx;24mIVD5asr6%ekB?V)7_Rf#r|6L!a zo3Fq4=JUU~c=78rm5qevJ~7P7VejF(ee-%ZR_R5AhjIG$^|ggO`t7F_{rvjP;r801 z^z8ol_kR4lKmAc!FF*-5cnOcxZ=i}Us}pq!v#1lK&;4T4r?Y2IU=}eUAu170;gA3D z_n)puzWSBzwnS!1s*yF7vDCvIw38ssB&(*3I+BzK_Hbp@BG#DYrS0 zV*~7a#X=h;J?=$34uZV}jv(-)TOEIM_u^+SUw!%J<>$7)QdmUELod05!eUCWa2STB z(WF*jtg)tz>t{b14|mgenS^!Bl9FHvyS3;@jhL`C=GFO+es^(trn&pgCm-*&Z`O-p z*j?tNqFTnXs}%~TDD%zr{%%JwreA-&lvE9`zW(Z?XV3odhmU^r!{=#O#dz(aBFiwO z)ft!|0y98-Dpt3ePegj;PT3(4sBof=QNwLagZTc9#5OM#ZF+>Y!bxsSh8+s0a>ed3JWSyWN}F?cHvyfbD9bj6d0bQd1j8g9Tb^rhuNMnHUh)3~$VJz;ef_Vw;eGAy{H%c5AG5e8tiX&~KF(&3gE6uxZ z{9^m^=b!)LzbkjI?(SYOvWmNmnlz%THiHcy-Q|;i;IH-< zU;YJcTCL9^>uz`|ux?nBg6PZ~)8u=0C+ENYC;v$D$zT7gf4+VF`rY*+YdY+2%2+Mv z7PaDf8n;(%a352d?BkE$|Lq@4HoepP2Tx9NZ#G?&an}v&7(!MXq;B5WJKL17EuN8eaoG1ju&6`)(uU`$hKOAi6$syY` z9g6i`=QSeic6+td(?p%>ATh;mau3z6OB)PJpAM{(bSvZtRRN4yG{DZ8Eqc;Ym!w-J z)=G8QEJjKMd?JDHpyu^*xwrSpSN*M(PsW{%--tOTF|I9?bgf9(6?L@cW^# zV}?zK*6!uymtTCXp`&kG5+@W2ET%0c?eXlr_m`^;!x>fCc6lJsbmkO+hz^jsNBbQJ zl5c&$7){IM!LH_6C^(L!=C`znMt7U{4joU6I1;bHd%jw{UFeYVHedhZi(mdXUw`~( z)oMz^6r!KC#O$vx~N`QJ$1eGD|8)FZu@LVfk)d^ncEU#FZHm4hj!YgMy1Ql z3na2uH)kFMu1UH@XK91cIvEHa4*RGvjXMjb-K65wartCrnl2B;5v%iOxV}La*Xkx; zzq(4@aJpKr9{06O+uhx`+YM`Krh6RjzP-D?NSY^)(ZZ@Fr6#SU?Pr3Q_}&-87|CnD zy({6DU0(Hrp8x2h{`8%w76`;BZqf~rqM|F(B+n^yfj8;91Q_gru4vo69PTx`yeMVN zeV0lSiC)fYzMjV2joB~^x5j-c9<@|E?UeV8+xvjawps@=Ue_=Fy6g__7Oo7FE;ka* zH1PmCd;avjAHL6%XGNEWnW79hQ3I4PCl$q!kQmX!757l-cUoN!hH@Uv<=hW`|6REh zj`|r9E)~;_}~BMQ)TRGx46|T+pAZL6#L6h({gb*JbwT8K5+NxP$-LO zD%_uTr$741PygYc{j0zDe0-Df&7b`4kDv9A_n21=hjK6}A>iYCF=l=Tk zu-{)jee&qZ=Dpp`_0838arru*%GJwnu5aFW)ywPKGPxNvY*_c8bX~t44{DBXTGTGQ zTwlDI#=2PcyImR1o-RK6sq~wvP9j4#xKybYn!pxAjcilYO?lGOOi&Aj7eJtjN~kyK zt;KM@y}M3&I6r%KcRQloEo3cJt938vC55@OcU`tl-EsQG!3wE}ElW+Wzq$PSg@>t1 zpE?03G+K>)kvc5$@BZ)yXHOovMqmo$Hoei5F@a=sV(*BqZe3_{;#hpANRWH_Ki^j2 z4754;x3%*<;PZg2`ZoXLJUY&L-}E9QW1IHh-oE^*U!8R8^Upv2AHM$df81@a#Ba!* z`zSHq9ZZF8;f|q4WBw04k|HH&N3rAjA_+58!|Q#y-ba}r7q;18)p42dh?DN8ZQ1Q^ zK6~@!uTtvr>b>RJ4{NzenXl`r0K5^fZeR=KTf!=sD-;P z?QpZr>~wj?u7h^)61zLlAOpR^9I0d9LljYbhAl%9*_7232T|SbCfP$(*F5B$8FR!L|M464-fJyi zeE*5emh&QT;vf*n_|Nz4y@vOFUKe9zAKIov-+=4jUF=!~N*6@424|z0AJ0QMR+Gi~ zc^`4nA;dTumxtGm_Ybe*`J?tUt+zrB@ZNj>=#%%$H%oHls9f~hq?(14%%ZI?dp|DK zwCj5>5*x0^n#KAqnZ}%a8D{l(3SVuv+p03hY${$HxdP+~jlsy3UJp7%qJi|J~+UKBt|N!WZamEN;g5iyf|b>y=GTUbK3p{%a!@$~+B zxhP5kc~z+O&Q&?aZBhxi_v&lMM~7^RW(nts%b{*DB6U+k2`i15C<3u)np}tIoaO3I zYouRj=B{o4rO#DjwEHIyBO|(c2VT4?!yUrd#X3_4lwdwCR-b(P`@i=)XXj7<^1u1- zD!Qki{;cbsINPS~(z_OHecrLnnJ_9r0hLD)IFt-z$q=K~5EF!rh_YCpFbdWsxCAQ@ z2w5z9Gzn!%r1|Mj{t*GuoZDV#?52mKdeV2>woh`of>!vz(rY&%Dk3(7GWHQ5G(9#Q znvB%Lgnsg~hqu1`&i-}47@Cke$$g4lHC8i%_s9|Dh%oG=K`u-Wk1Z#dgV`>2O9UF> z2o_L`sgLGHT=wmwkF{BPayr`AzBhnfFw-cpt|sB;OOuzrv~Jd`Jh0GY&rF`J+s5xWJYmgY2(_S zM97>!KRbQ=*b${@gv?Bi9TW9AU8L>xYqxISygRDqXc9Xm@*Z3BJOCro1Sxn}fEI9~ z4rb!Jt&Dx<0-wc=e6A(HmG$pWt)lHk*}uC7J|lKrT>+%bD<2n}w$z_cj?$-iarV3a z#ee$#&p!U@*Wa03zqxqy)4n~^9Hl>veUl07c0V5HQ3cc$d;#ZBm5g46aM@$I(QE)g zfKj2rV_Z^ExNG}WZZ@pQr_+9%Zf>yBZu}z2>B1ndZ7oB!V`!#apats$-fRoT;x7tJaLXSXzmpz?0MTYR+J;-w(qxn z-fWv^XRY@k#&&NyJ2*U&xE#&rZ6ksFWbbe~ee}u44<@tGY~sz)#j}Oe{^I1K?MMhY zn<$X2sM&Fmv&C(6M3UmT&bjT$s4VNcn$K^%eEilgWE8ngtIIVslV6vmpKLGp!xxK6XBMr$t~-g-MEJ zIWHD`d}`Sv^)4kgp=6Z0yjsQRvJrXbu!Dv+UHfQx9_w%#NzcR%|*lSZwP zs1{{?wpl-ape{|X9a%92IY^shv)VL6ycT5?6-tki;VRS>4IM<^ie;N0)vKnR7gsYR z#i&G9RE3SFCHb=F)|s*c`&?AsWQdVh?}(jA(yh9pnpU&Bn@#)u@BATz9ifXb2YX_9 zP7@e1$YIl=6)e|C1QVnT02iB>H=DdXchj-4kq_jHV(&Qg<8HkGIa4Ke$Qj-fj6wlb zFq!oV;i3Zi{^3tuzRTl^iNNAUQ{>J0qYtUiVLGS!K$=b3Zi{-XnG&o%x>e8ST1^&< z#p6d0nkE*-q;D<{_YOy+gIjm*on`?~&1?3f>3Gh^g?4hbUM{v4 zlgWUbbR>*zCzArXPcTZN>+Zo61tUZ@(xR1$e_&@RT0&z_#Oi@nL6(RiwAD#oN> zw^QU3kP`s((P8O)DZCHk9T)=n%H4G}8~x0I@Y&$?zirN>-CoOHm@{82(TqR{?X$~2 z{%4`NB;SBLCoCBf7kdF~-{rJ0w#okWvL3Y?OUYnVSMVi*M?J!*f+}E!3{}Vw5Ww!* zQQ0l}JP?Kqen?nUq-Nubo>Y25fTOJ-#Hw}-^8w82oQ1NgM_(CV|8>FS!yo-_+ALnX zH`;EyO^4H^_yQMOvOomH2CEfX0TEJ!0eymJJb2Lj%YXizuRgzbaPLO3zh8_;Zo1DS zHW%vYJ`tqZKogIqWCAm|0$yR63FTxTu9VHQc>m+(!*}=Jcn#i{M|0F;a-;d-wO(?l zie#FMNAqJPNTJ2-Na{Hz2fgHr%jNRoJm;LszNji6D){35!w1%<W7r z=XkWQ{mO-^tgFdv8oRVyoUP8DEYB}uigi`_Vob2A8V#qOs(3Zgl!*s#ZA!T{iK>+O1_srTSWCUKjx zJYBC(wx=A*{k`L|@EVig11#mEhB?$pSR8~|> zk4M*k!_U8-*X!k{-=F36Z+!L5dO9g*qswQ@rKQWo=E=hcCr{6|+q`Ww8aYK$t_NGYl4L z3Ngp1fnDV|CwQvWavslazx|8XUiz{tW@gOg6dElnI}V|)rjzmB-udYxB4Za)A7j^S zR_7wQ@@1bpA4SMOqF^@3eb;(e*Ee8K<|QYFcZJWAO|&X>T9l!jloO{pGHqeZernAo zcH3FI)p21UD+*GfMZeiBL{rvCD9xnTxY};cngxLIypj>E`eN~6Q+7yi=Mk`JT5clrE#;{sJd|4O6oRkdjt|85t+{R z7we^FCE}tgnx<)!tk%t_DveA;+b&mSAoxCunJEwzWlbs;6)_qLjZ&a5wH)1f^R3C< zS6+MLE$2sz^QWVF9O@B*qcR{nGUL=u$J5fknsdwKR-4u0^2yoB+K^Pc+Iio1EfM+P zkX3S&lw$79fGlb~(U2==p>Ucpo>V5$hg_7E5JF;5hUDSIQoPnWy|BJ%woJ8e^!YUWsEbpRXaSYs&&H@q9G@PFKzPD?A|XOUVpio-j>y=oS&=oqy1}catNm23uJX6K$4Ud zrR^PQhIeIhPU&uMS!NKaMUwzswFD6Ha<=$Rgue!^#y_a5{y?WD6pEu2_uBYf$UD_y8?7F(5?ee6I zH*?#nLCE{*m;jZ6$tk#9ExJ~ix$7bsjmoMDU2g@Gq}2D#ax$I!PEiDa)24 zuez;U`=XxI(>)5MIZwrepmj`0jWYXc+-??69-gi@%bc_*)TgWj^32dgj*a1pN^&y5 zQQ@2;V&}XAs301TLOmi!-j|vaD5xTCS>u){02SrPu>nzWd9gfMh%z)15W9BSEzjFF zIj+W|yRW?b);sUaXUEJ29js(zbk*0&j$#Q`V+RX_$mWE-=nU#V)3n)Dh4cBR|0)&; zw2Oth$`Dm1RnQQ$q*vy21DvItDQz%ln5RUcJ!6W!7uH- z@)xoF;rYX#^vmxeKawN`dQhLUr3g~pc33oa_gXO>Wq~s$=gkymE)-Qp?Pk~DukX!n z(dgP_@0DtLlVG|z&6m%}Q8+k65`(s#}5aO8`TW#4z5tIIGs@PSNIUT+tt&&H#fl~o`1`jqEK zw=d709qkMv=89&pCG>kWlKjxo=0Kxf@SWP6Un$ z&)zXx>D+X-cm3wAa_LT z%x<(tMv`(*#l`7416q#M2Ss5?Y;)-x6NF%#t&Otk``$WVjc(q3{k7M=w10RL&Y79= zgmMQ1#YnrYob1l%0p3v7KrnJ*HPnB`nD}hU`J(!_s|W(S(hnJvT!o^Mff#B-7AomZ z2}%r&o6E;pl9$MwhR{=`Ozgp#m61Biy)%WitZ>w+TWPhIM}PVH!7ph07qodUvD4Kj zVjsnb++TEE$ocH8SLx=#G)Xg=jmjd`lb6c+(ECHG<|t+;51A(fLW;6^-hT2YMw_bI zchlPl4!%NgMj#dA@M4~Om5q>%1E3T;z|rK;hj5tF&wt~MZ@>S?rz@leFd@~cVYyyg zhAA|o+2Es2M~u2@CKV5!>IWwq0~|13)3!MsJvCorcBg&&`qxsNlco@|F!N-BHe)2@ z$<#ILZCb4vZqp|uNWEn@Cd-AdR-4QD;T?r@q-9xlkE&|E z-JF8BEXO2U_b7%j?J+% zGhY;@MC8buF;QJ|PabQaLT-^QZZ5JUkXbQO$5t|n+Tp>hbUvnSce3a=ZQo?i^TS*7 z8+TrR_07ZUx8Mtds`rWjCK6#ah>|3*-ysb{t+RtvOtX~`5BpP@;Ge7b?S;A%WMG93 zt28(g+A+k<{&bN**G`VPwte{il zg3Dv7Z#$UY`URG5#AQ7F;eokZzwo;Eto_pYV#l&@&WwT5B%$Bx_A>UT{rXHcC%#{J zqw4w{w|@s*0BStQ8^l~;?6FI;8F-J3!6h}2KOBq$X@_Oev=>W`t%s9aW>*sLAYR)4l!e_F_C9nP|#F}RH_2nfmmW#4+K3vnhcA#ni0)oD}qGqW`Bf{n$D_3{$t90%iGG&>!rL6mcJP^Bz`GXM}mCh6hWq+uvH zP?&9h`uq9*Z;$@w|DEyyTV-8>G{}zxMR||BZ{%Z#P_wkek?dv4Jtk`lHq9`OClj zE7fSf?UF?@UrMAdYfsv&a3f6Ob5`0Aey>e zxDLD6tg7+G+=L<8F1pQjyIHdLW;q~u5OEQp%C3X~EJF+sh#?tJ$knHkB66gdt%o7d`C-|*Gp(ZTrEtuWhH4yHirp~fKf zc)_(b3KmrBsro8&1udcBGY!u$vmXLPJ~JNJ6^8MJFi3{#pLef_66}Si#eKH>9gwj^ zWTY`S4YR36c5u$AW-<}$iD8lzLDx@RUIY825#XI{m;miyu-ut!RD?~9E_{1dZCm-h z|2V(#-`AW?vq%SpiN=1dd7W}EDa+~%>3k-a_V8zN=>5?zqbNu+IG6`She$7D0ukj* z+SveqH!*f3`O2250PAMCezt!2BtP3C3ZPJhV{|>P&3LjGR;w72r8Qs>L0JNBm%4Km z2L|>aVAI20XzoxHLAP5;(xzHqV<&e)#lxQ@h>hntI_qn@%(PVL8To}W>24= zo8j8Qtt|Qe2R|+=cX)Ke1nbS|<+7Vh=Vieu<)iDj4DR?itk%y;jGAU`D9U=u2Jh-k zchV~L0#T?#Q3WjqCB}Tx+;m#;MfB&D~ymxSoUq(qjlrgS-sGSdHB4m_JOJ`|I zu3*`w)c0-F*u$W3kR5(dcfo0c78qs@$U><{PKX_ptlg3%5S#b5Z0zt5ZjYq1>$hn0 zWa_w>ANJ)0$cT~RmZP#oy>>n9&2DEwIYJe*sxk*sH4(mwXG1a&lfnE*>nesZtb}>U z=PbOREq6aBdK(0%ySDem*F#c}xLt0F?7p)*JO>W|(~je*3{g1iTOyD}ut_%O!0b(w zHH#)k1$$_>^djH{%g}*2?~yw|pbBJDRuM3%M3YQP+duh(>5VTn<(nkXY#@@<5loV3 zhOXDHUzOa8#VW1hxBnr2dF<=oG%i3&mbBSYF*R52vSoG1lu!W14w`hc;=+S6gA;sk7~8! z2^Dp=#q+a|KAw(_t58dmd|4!TQx2ijEWr_k$pr%&J6DwEwHh6G5m9NoV#ot>7`Wwe zOMNtWO38AxthPLZDvkDNJjR5y2)Ulp-Ac^qIy!iwqLFLjUqKrg8#mOuXc z`LBH4)3H&oWb8_lp2RR%F0nLV=pGKf;|EW+lqfM&&TtBhPMg|NZ6B zO$$XC>bPw}CFaC5F}obthXD2lQ>u9s_7A&yG*R=~w<))tmS^e%K)h+KTbY=}n7gc* zHD{AXi%@^@PC9s5T_D;jJmM5a-WGxTPoF(qU91nU&GN-%*?izGSB4&=N{f9c*u;p4 ziIPwpYWAE%An%6o`e9Yd{r1^MKlq)O ztMcIbtKN-F5&NZj2P(_Syr=>k5d>h;M4+-50}NLxk9}Tj{d8j8dh_IIF&P19n+`ds zX{Sv&E=Sj{>){<~Cm^FhMaV+%zPHuW$M5~%;*yJds&hfdC4*uCohDGf4TFsLlTW%ATEE`Ra?Eoe@{r;XCH&j$*zWdMa7Iva=Jb znCW1A911=V6wY>bM`xMRdg+-A?3g*Yz(vkPL>vm$%FNRCGT#4T8Rn=DcZj#EdP-9d zBUmC+Nf{h81Qw8@1mWH9^-%Z9pY6;;dP7cqZz&_UFk>g-`s?z&-v^viaNEZJ`v08& z(!XCF{JMFkzCaiQN=AlEL`Dv5=B5-|$_Ye91i1M8@#XyoqI7uZreilm1hSDz3T2sd zWa<5ogX2&dd_YbxpeW&ohWILzT@2Z<-P-x-v)ts`5`;QRqbb8#zcn8KMPXc2B?Xok zH_MB|!<&6-S7(=ti|uB6dHdF@u!2yKwA-dneLg!qHE>bT{YR&-zwsp>)=ATNJeo{q zmuF{XS@wPB3a+a0<;7~b%6DdbXRn$S?17xSl(iro(m+)KRrSP7W};c-?8)k*AI|6d zJm%Q<4!#$R$CJIo+rF+~frtp%Vw=QF2U}J)HIH$P!~N`z>et^SP4VgDyk6xTV<*Jp zuBgLkS~``WBE+0s|1_kyxHwrnd)A#S3P6Bf^X0{5ookG|m1C&mG?XG&VtrDu2Skft z!An_XKQgOL%bh#tvl-7-%|rN1+0UPM_P%%xKAUMW$u9gEc7Y;IKf(UgjMx!xH0$z=TL zN1vRZKCWlSgDB$!ZqtB&ROYbIv#VVCX@P;2M==M>3FhUZHmIDuHQDB5d3nv zG?BuWP1`g*jRI!`u6(H((FhPj>44!9GdMOgOEQ?-X!YQ|_07B0t+Jl%vG?`pXn+4^ zIWAF*3_92XrHd-rECbF4CNmxF%luC4#}KaSwanWTHQ8FmRaO~Sg|Di-KC31#0B-6aWNU^3ag&SQ{n)}#w8q37FN|#72?A#2UE){jl$>b z?k^lIz?Glt>goUNiT}K|nF!{FTsks_GKL%A1?0y-Zud%=>JZmA?1vEmA_xIFMlQ#$ z=!mm-42B~yNTbH!fdBx207*naRDe_C(uF9JMZ3+W`N?;SML&M|Ev`IS3HTvGPc`mh zXHf_B)Zh4;149xVOqI-_*@}_|)f)lqNX(qucI_&o=_S^R07^AG^JK`ZUOksZ<=J`feHbx3vw!&T)A`|XRfT5b>(P9@c~a(*BYcO>oBy8<59I9`>GmE zW^T4`^Jy9#h#%W$SXuYEh3=nvpg(u4zsN`a{2wDgUx+}N@=(5F*U=eZ&><_xb_o$X zH_VV(G{hneQJH4s31mc;dm{BDjy;nj9zJT#mQ77^Z|WSCrm0`(p*fByMSs4(vBcQD8Uz&|M*R0XU@AZ$DIQ7g6Hh_fkUy-FaSkLy%(w~aG0h*smevZCv@N#bNyJw4fa39&cF zMOloP^QbC(s3l(~=W`ShAGkJ?&3a?m7HxNQbgUw&my~_erjpZUy>GVQ(w6PDf4VX2Zw+7y+3+% z^7zU5q7Gp;@>`SS#!XsxIW}auo=v8EZhs%+x%#QW4{2T)=1!l-6n>uH|M@0>K96p` z(mq^$$3cj|5Z*Z&jUo7)2OePF<-ZdQ#zUYB8Q8!C1+jsdOrO2C_~4IS5Rm4SQlEq( zRFPTxCZ|3pu`D@li1=c$dGhG7Z9AkUZ??|Rr^XP6$QPIbomr6OyXCS0K(Y&=BtoHt z(+eBvmMY8r{xpp5y@_JnET7Ov_c?)vMV)|vA{jq>PX7IFu}JHdyvzM6_k9S3S%L?V zQSNndzxn9B?MnXA-~JD#`}-=9o%4t}R4#S~1u2nK7Bk`7dbCa&r-jA>AHL8 zxxymwEtvL7t( z!>4bWVzb@C6)HQfs6pNT()=TqS_YQBpTFmx&JSE3$U^4zJ$B1^% zvVDHkkI!8KFAOep^(MRs-7q307!SWf0q~H>0wz@+G}Uy4SY)?T+7a#Y^xzZ(aso$4 zMl6rtyLj(=MKGfwK2bD95zSekCTgZxHRmKM$bH;yHW#avZDQQ6S0_&iwmExBeV<~3 zsOVb}UrrpJz01P8L6z(#R^H$)m+%*z2Tjk}6ZO;4CPi%dTX0iSB-Szq6wcq$_Y5&>Vh9~|8w=QiupzHg1F?c1uXPfng{Zk-EYZu?wMMt!?JKReTu zyRKU;*M;Z8*|SGa9zWZ`svHB1JBPS)#G?`_ySSbq@Xh<3a*`c+Pm)+|o(MR$ge#iWKsf{t@$ifR=tg>_ zm!J$cMASL6w!I`a=NU{uG{9M%q=#D0jrS!$q5>7oQdN5AT77caJbe1myxE`cU*D`R zRii7*!n604D}5%dJs;PjN!P=6Pydji!yY3B9&D?5v!+zvyaUhE8*g3Yf9MpZ@Fh%k zr5umoGVJo99ln-Q!mtQzlt~EEdZv_` ztm`lR{2M=Mzgy%Aq@E-;8`&(j>-9?q_1!V)wdP{2t89x1Q_CtMSI?P25<(4zXDIrF zZAV=)$tekh+-Tp2P0A?*B6G9J%}sN$H=C+hjN9pKrnxRg^V7%Az)6xzUE?@6?MkJr z3mi|5PoLa>@L;p(_lG-7e~E_b;Ev zHvQbqxy>r%eN<1=@BDMW>E5_`>+X%)TZ@OcZcPr4_VHD*&&HJ}?dhEQWR1G{qM066cwA*iW3VU7LW!*Ox3e0KI^y;+o_dNMko7^N7n zOUSyoFu(QX7mMC02q4)#)}{bsRKhMS*?Ir$yG#*xzAEz)7nu~&!_|;(m=yz=?9&gb z{V&Ao9!bYW5Q8S9O}{*gXD9QUcW88gtj3Ahn`A%+A+4$meS(Q7BDziKt@m{N%Dv5_ zGjC?dfLczYvQlGTlwI53n>t|@%Mds+R)ieyb?TVl*p4-K{QSx-3T1)v5)#P)!Uh247BnIU0{bzj*%a z^!eHO`RSz^g9L$b`w%bh(WHWk^g> zj?2}>W>I$fiqp|C$i1AqJGoxQ_jjK>GJ?#+*mLS2#HUAQ|q8}kcE1DP5* zA{|nUnGE0^k3_Hj6a&s2iz9Wrp*|5AF$l(#9SwlEVLqxuOEJtiKVumZf!yxkCwJ9H ztAQ1M_ZsZ3L3Y+R@BdNr@ICgCUGTvL=b6cQaxO3&EEAE6vV-$(Fc7kHlhI^c2E<<4 zZn3!BZrj!BvX{P(Iiu@R+KA2TJjrGWCRd$ufRL=|Ul?W0RiaPDgL zm%t7NP_(Z3q`3BS9#Rh!DX+C(Sl8t&^Dq3Is6vy??ow=sl$Z&mCI->eL9=M<7=5=E zNgCU_nl7F_E;+Ds1SXOwVhkX=lFY<2Gpi>yv%WJGuz?*!P!u3WS#eI%_x=3(jZJWU z*B>10JMTuL@p{{ZP>shU720-vOq!B@^wGO@6^Id|u$d3;`0zN#s4DenCro&doyd@=m+cJeP~5c700E9;6w<;)meF*_{kk@E$) zUDTpuE<#{Q3z9`F)&jok6DWqb}cMgumqvLuszxm3eS>Z?3_;T{-qtlC%?UODW zX@BYH`p2ty_YC*m%5RP)?kk9W!_~fZsH&???XFngHLy15^p!AhCKbknY-Ehgq~d~@ zdl6U3Bp#U{L!kQ3(}lqSObTMipzV3F7o(jZL1++@k{J~{YXLdCB6R`IhG`<$t|m*n zpx$;(xi_nQaNwMg$@)Q9l=H?EfGa`)B1yfPdFRC&vmTA+lZk7Zw(rp-TrSgklOj`V zDoUlZb)bL!B{&bu7XypfVxtKbY>%Ub=C3ba-%haLA!F+AQ+vsNi-~Dj=ws+sX3@fQJesp)8TI?RKFC?_h>{W zDgzubhiV$iU6PBb5|R54{+<8sts6IP-MLeb_ix{OlZ%-dkLuuZ<6)fB=Jaf{SyJt9 zzV^zOfBjeJ&-}6-yn|E%bCc5i9;({Pl6atNIby~@LnavctC`jCTJTj(Lp%N~fkBS4 zBlRqvqDLl`!5a?(4Wk~7#Kx8wN~CPNP)33h84ZC-Gzc63INEu@1~WP<*mfdP3||Z= z&>{IMSabH1-*2BkDl1P;EDOPMHdU3B%t$p8$a_!3t|+UjEX$D%;h=232t{3n(iPs0 z=he}{=%B`4g?XTHVN5)&F_o(@bKNxqG|2WmXinwY^7%T(=dO1C$FJ!4n7a!7T2mHb-|kZd1DiU>Y^9G{+b_h;*x^^Ol;v+w^I( zOqxuInTar51|Tpwv!tpp1}iz6Ou-IfMW`<}n|8fo=@#o=Qup-f<4-<}^P1ki%P(C=F!k6; z=KU2Pc~Iv&-aYh8U_$T^#bmD<*R^xrNDb^AIkRT7oZPwF#iA@G>*ApGh^~ev4J!mRf2OEf|Z77YcQyROhJcS zo~b=jjHvhUJv0Ii?BN)i;A+@&O*cn)@MG^}Tg?n*?t8PI$(fn-YbP~1u&czPT|V#E zPslpWN>DLK7P6dUJF3U)i?bYaQH8DOs+0N1XH8Ie_CvM^ab|WQcoPMfAu3q6fI}S+ zGxlfG+&8I{TtrXB#qvTF95m&XbAUv!GS_90vZ}luuU6~L=JNdPaZ=eoxS6HT!hN%S z|Ht3Ed29ddd>t2wdb=^B!y1QUWkL?f8NopeF%Ctrkwd^P$VG>hkAex)X{gJQXC-n9 zA+lsy)cUiB%Mbr}{KnpDH9j~nP#B!CyGKG5M7~*XVr%7O912{XoR*U_U+!t#c#^u9 z@7+G4Lba--+E0FL2vFK-D0l9}L3rL+td$E5AoAXMhX!EUZSIC_C&F<0fMJS`7$ma$T6geI z7+IU!EuipaSrz0gr@kml0_WIySE4qeK8A$dmstx-mBo-oqwYFdX&cFPV8xt<5?p7E31!fhEC&UhpNzI5*S74$f zh5!askq12u$T{nJfItDWIkR()dJ~3^U=L8?d@@NfKY#CsZ`}TR3j5o&o6Zl61}3%u z24h?4cfT zyC=4Ky!4pbukktTCc=}vbp*z43yw0QpA-|^D>T9^eeCI%2=$7CXziOneW zy<`PUa^@E;J(H?QiYn?uAWNYrh^;JZ$3(;2H)v+6*xYKj!5QiwVrYgXKp=Z%5-v>a z$mQokO2Tl(?qzo#O0dT4IG~Z#H(-tGt#3#B#|ASSI75+;RFYXFBWRM;r_`kN+RRed zGkgzcT%@*B5!&UYuWC#I7?l(S9=7t0r^up)CA^Pagj6zqpvy)b(qMxV=Zy ziku&w0`lzGfxv3y98!jNl&<_EL;zD&a_nq0;j$=*OLj$3j*Sdv!G|Hzn+VeNDW=)& zFA~>PJtAV-HK)7Dy1#aOi{KVbY&XUJ{$Vw#rqiQ(?A+)8&b;#mC+1-W7NFW4`9nKO z0C@;Q9BhC)D3mpND=Dy=y@=D2s~9?5@k|(3hq3NJ4tyo;6f%KjsDKP6gVw>+u8fG# zoX9hg?L;A0JuN{M;cA?Oo$6s%EE!<#v*2O_lwp+nzH2DwQb-NPN`r7nlW1ZtRC*F- z4oWhd%w3ngcTDC&X*m&l#|j7+K@`q;Gx25Rh$S~U!Z=?RdaVX4WT=H4R6rR9=o++a ztHSi#+(kQ;Lz)8Hrd_ z%}{YDFe&}`a8k}g=|qW5o6VA9bK*aWpFYHPU5|=Z0cQgB=7^FcGj(7}IWeQG>w9<7 zr;plRXxpI3s7KZ$2w8o8>59pCK55&t^Yas+D9WNFsy(`1r<3XI=-|o8$+U3J^5M;U zj~;#e=+k$<_oHVpLT6RLtJkRr#ype>stWQ_dLKn3nhr~Qvfz<3oJUS512Qn3vG>HF z;J6--wwsL+JbN<(xvD6-UdH2M{orTKOW&uv-!wa>7d816G1>ix|HHpI3T`@?6!mmA zulM$^P3Lo8PKJt=j2t-tIy~-p;kp`hW(-Oo2L^C8z1s~zS%-Z3!8c(%M6l@97~X7G zrCb4;iIEvXrlb)X0o@fTI%J+ISYc{*CF55Ch}c~f)C`!h=K*m6!cJ&PSA+%zz|4|WH5-hWRWe|z45qA!xb(hI4Q7M6 zhy<2XKRDqTrFUYcWe>|&2?$pZm*F0eo_MXij!Gm6P_Tj>%poU`hpPyp=|W5hLUopC zv7F8bVp&Z(OOaG9M^j}8rIbWnJ*)Qb!j;8%kHdsa$%V3-a5>(4`IW=3eEIkbZ%Nn2 zej9T#vy@}XGLRexYpAL@=1@=>SD&Ke+@7$$3N1mPf!m)F7)%7~ZOr+U%`t28_8^1e8 z9n)l5dC$Hm$V^F7Y*n+Fs+k$Gh~`AjNjAsUtS%1jyj<_y81l1t7=Mre@XYz(+70qd zVNz6ua|Q1vH?~X3(w;dCnlpo9w@bP@M@hj3V>o~a`D(xen6MZN8?zEr&G}&wYjox5 zvKN2R;E^Fy(rl7xaIFp@R?H>}%O*-hS2G+NPEpFOshX?Il@@!|Mw$*GaHy37e1$@G zjyMbqe{(xGnhl6uvl#oe5#^LZ5md#<7*4Xnh`n>atRD-XO*-2uw(tbLP>t+kSQ<#^k)S)LZJY3lKCWr>ewW=JUN@ z{d4oKIeq{8&)@wqdgqD3Ld=q~83>ZI0$6Tso6tl!hYZYWq)dxVs!z`9m&SY7_RCP! z)npdxQ1Iq*5fzhi)R8KzZ#N%(_`$`qZqQ-V=w=i=in7q{BkW&2FN9_-POeg29 zWXXAReiFvj@^a}wnUsuqzL!H+jt*&5%CsKexLx16b?xWAC8N@k?JBV-tlpdu1!5-c znQE9hpG?$oL6*!sK~ys^NHI)BoG*opsK~M*-FQDChUN?-RdwDIGZ>~Z#zwORruEEb z=Wq-JNW3E71!xcH!48%ohQ2d$P(#E^oY~MU_%-#56QBzSu1tiBuywhMI>dd#k7WZ@xXbeYZcqxc~h>noy9WK6o*K zI%Ng8ZMrT|1H=v?Au|fGoH03FV*GTnH|pCarp`OxuD4y>Bow;EcKI|E?vsx`c=y9d zN_Y41(!QHiP*X4wR8`H)0g^SzaM_b{FjLYY%g^e%0@=uU5rHWv3-1y=gLA`=L=2%Q zOic!$bc*b`;4(=D%fkKT;Qr_T(Z5$t56zDN8@R}Cti9mfGg*&&l9vINOyvI9i$(EI8z zC^C^WbF+;XmsoALpMG%u zgCDHF_oMrN|L<+y`woXRy>mm$V2h`p{K@Z6i{Ju0i*pWSMJPe=&O^!hf{d6QlQSb1 z3NsK@S%aY)3`&m1I+Se)DhUKtF&LQu%0xbR4nbLHV}`dI$tR9^ZKBUh3D|)kQIxrl>Gs7orTe6t)}N5H41DutX>@V~AvyZ3K-D zZqx(jH<<>RJXub)3!oL|28ezRBLo!josn^j=-fgMv3*pX9H;+?{gX*Z#< zo$L(`P^Q9hQP;*GSFmF+d@&m6c!R2!nVEKhxJ;y?g=aHy@TR?Hri^XeUVG^+;tD)e zTLyOSfBAR*wv|(*Vwlw^ypdy48Y+Gc!>0Lax%(o4g?J}pu+N_6VYGwKi5mFo=gcom zy}LJwSsi6h$yp=_sSc7WGT0!$`fNT#yU+{fU6c_~{KN0*KmP&8j>*85{-$f}JK%VPS@GcC70QP~24CGu$v1fM7 zj)@7#Ihk12%&Y`t7nr@9ZQpL`3i?YNPVSD3b_koN2_=la*uw z+O?7|vfByfAZBDVq#kBP*tN*&c2~g_hX(+7AQtTeKSTyj1Z8BhOr|j1xw2INg$dMw z#Xvh`^ls?J=vw$9Kep@=W`Yvbdf$(K9DO2$g)l; zfyWwzyG@y8{V%`Wy?g)7zxYkJH!?{^>PI7D26HGXautQ(!i1Q~7iN*6?fnn){riZn zq&;6xQnyrGs>PI`B9b$)BXULIuI}=jwHH(8D@M-a@%CnqC#mGm2n$?+I}G4b8K&JC z(!mGx4ZMey2t=+XTIC!mj6ezMUOTV+8L)q1qzHi`k9w zYSEf_W^%|ZmW*J=j#aD(Bmg^tvYNmXjIvQMA@ajf%I2Ud%-)y8WC@wn6pCRWfGk#3 zWlYIHF=o?=x$GCscmDBz_80%{FF2l&gNYai_jmsnf5%Y1z>Ey%vlMD{=p4D*qSXyXp;GB#yxv0-OymfWVAQAPF#2g_)9o2FWuM6@Y-W z{ozmhfAV|olPC7izhB1WOK#$ZS%t9bR!O75T51&#O|IZXX;k^LC`7kLp8b%Hrsbpt z;4DYcK5mb``r71`n=xk)*jL6L?1`LFNp8%pa(-lf1UMM?j~})_dylh-q_Ubo8APc| z1~sS}`JyCnQ5Jv}<-~bMfz8y1DtJ%iLa0%@)bwG!(`pRD5p+;R8b(|NTz~*wgvrjo z41s5JOyr>oW^^6&Y6D}|y8O|5 zsgHE9hp)U&Z{5L-IXj`Wk?kToiFaQDdEMl@SCCW@p4Q#E2@W=A9g0*^>~ zfH?$TIA=sEK6Z`3sZq)~W|b^`&M|6CNtL=j^-*G!rs-phIa=!auFq||?UP)bpSs!J zjk|A}DLV&(`#XR4e+Gyl*f3tPow%5;Mm#&g4vdhnJMytxLS0Fg2Oz^$C%~UQ^e?^` zUKVFSN2+9*En`@C4O^{YzL|&R7n9mRZYCaN3rHWlPk;2?(OKdrCls5w+E{MRQ>)1B z`l6?eeQ9s}`jPCZ7Hm!9R3vHcHdW=%o?c2!)W>$Y(oNcKx7wuDa@DtSbmQQSzw|2> z*s(JJzH~*UYT!zRiM(S6_T)UWpj&T#^uxl4ooDugxX*LtT`hgi5ZmP(6vSW`$dnwL zIaiE`NVB+5m?v_j1-6scE6nXaK3AaYcXgu;VTFv;gBeMH3>D-C43sm(23!(=W({T_ z!#R-Q+``>&eVywuxMEkZADKDy3oZ|l6Lc$**%3t5#B68)41h0O-mY@niS?$M`m)ETcpRr=X-pp3IO0qQ;D_m!e=%%~`TajHykjkFnWy zUE4~`DW()t?qgOpm9~k*PLrta=9M{V-y1o~F^aj<<@U+5vv2)G5VKqEt zHfV7^6VCvq*}M@uGTz}BUi8De#&#%-hy;KcfoT`h`{Et2Av)4v5yoaw$r02I=*8iE z(jEEL)QHpoWF_y+3?yVEfAE8Fv6R-(E-sd57g@_mcz*e`s_M}=9RHPXtn=pbqlYQw z>FdX7=I(#@XYm}X*oPN z=aX)JK})!_TMskswqpa&MF`|U4(%4fBjp{=%_|rvk4U`7Iu!*pqfMZI;PBF&n<%QR z#=cNuO^KY-OuYCIT$&IWG-d-E2_wKvObT+kZBtHStx3vFn?+Q>E|Bx^WMbslJ13lw zlTscB7UEuQe~w?;4_{oyhZhEiTXQ;`Q7CN0D1x!^o$I6LkGEZezSllVu|GEsem;8r zTfh9lAN@;b5(>@2o}`t0E?=GcFu?Mo;#_S7k$% z=}znh1=J`2di9d;`l9(B0nn{V&33+zP-kC2-5-AE&!gN&Kxo$@4 zeNoh0_%N33=-MHb<#M&0zgEqz6ad1` z)Ao7d!?4QR4MU?6*aRSU!yOM(rD1`fMjBz667}!jw;%nm>N=q$x?Q%Lvu=B7O^)4b z|H?1m+B^g#Bq6)^%U^r){rA8BPk;3EsmxNbzOlLS_1jk7DO^!alnTInRT6m^Lhz~EHqS1qgiVzB*Hx*x0YP~1R7Cm{LPQuM?`mieqsYg9R zRiV)Jbyz;0uuKhN03RJ=bzdAQT01LW&^6R&aRz7OL@JlT{VxJOO6H2Gva9 z*fi=LXESIrBPcPOTGlSNYqX>}6Or`2sZz=gB$`Bw$%J!R72;qZ$IguFs_t{lrjCf% zf=4JzHmNH=I(TVx`!#ViwQjpy6l{)58qb*vW@k#;+sj}7){{>jv=<9iXclHOgCojn zNiu<52-j}iuJ&fte3YB^gYW(LaTut`RLP+A6-0MWFl5#Wdng>*}x7lQ4%v^ zFj*$Ylw&{eAp4{REUs3RE_r%L#l#OC6rclDe886M7*YVp%$NWoQzIY@RXLN8C8fcz zH25V9a0YWALEc#vcAgm7y$@Dg(L7m{03R&xhDoLbMQ7+XNDHJEeQZAXD82vm^uwPt zZ4Z;KmFax0XbMZjHk-~DX}wkF14kipeErKW9lv?|kN)X*9)5EA&O7h?!5{zlC-2_> zjlc2p?%(hBetLR&`TXGe^=Gqkd4Ew`u!%c*>qhj{HGNT*DNC5nz@-wW=sNTpBhT7NfJ#ECpiLe&S|pt;==VE z*hz*+B2&Qms@6=Z0Xlqczyqkuf394fAL@a>T6Fgs*&Ey=_kMQC%5kA>#tmY@Vy^RM@8f~ z-K!?m@%-kU$s6|~YiuIa9Q#mtcFqR>jVsB4NHi0Z*Sz(qQNTuSdhbp;EvfH)5a)|9 z8OJW=-u&K?n;xlmWkF$d6!xby4q<;{w#|#D+mlb&wnPC2P-P5LuMmU3_H&1)zk4$7 zTvk{C_B%r`hG-xU>)<^um)P4wj&OvohZ96an= zsiYVU=9r0`N|!a$uwE1~i6&W0HPN6W$`n$c+Sd6_gnO7XRWoW+t7x4giE6;0jum0b za&$O7yn8p6buq1}o^&aa^W@6Hvsogp*%hJy7a}Q)%B%vWqdTvB{a1c*#s!r&-rvj4 zv9GA8Trs6k=bTL$Dhej^eYgAz|GmF?|0h2?eC12c=vn#UGgD+?7%6l}lY=Q4U|I&3 zm14?72t}o8p{`-BUoE!%>Xom3v)H?4nmz3p9K7?$8tsOjAl->}uGFJfDer1r3~_YlRx_X?+DpNvHnnG{oH=~lly=C-5>mgfAu$R-ke>3sZz6F z`uG0&x5z$u?`M~8@t$n%%n!f!`w#Ejn7;J(7vKJCzb4~JicK(N6?3KxXcWmz&XJ?s zKD=z+G0Rf?)e5>tDA{PGRQ_p)eAos$4g+hxy}i`eyjTJPPQ zx)D2fWCcSuL@pGpX2BK0B02Kxc=U6e{^+#K5CX!Ecc42V3D|*4#0{2P%tk0?WNPz0 zlofb{vO-EI7~KVE0#mZsqby<02KY8&&K(fcG)olCWP8-u}t@bW9yr^iS2?K`8r!@k*wzI7623>5IN1M2#&ej>1dR*N^qX)$tv+R$1wF*vw9nfeFDswNUwe+ zzB2Qg4NTbKYZ5D!yrT#ho7s@Z0AW$mp^{P~9#*#oQXcjU*~srS-H5^treS+xPaf;V zSx#6yJNf7z{gcqPo{)4?y>$J~JHO`kr_<@|{NwvS{RjWZtD5DaF1ZMgd3E1QXZG5! zT>tU=r>N~e|4;wvZ~nzE9bemXqq1q%LHxt}_vz!0#>WSL{Ij#O-kv|c@V6hmzG;ie ztQgH>e_E8@70!&}_M8ad(51ef?A!XBoC6^fToX_K;7|Of(Z2IWeiWSZStWK6Fm;K& zv&_*ld9RjJGGn;tEdxVP+F^oAqc=!B_$nnxuz*K zj3S$PPp~XN-#5rvW6wk>MaNFKYS))4=-P$Cauj8sdZ?M0Nm396&z6zRJmHO(@6K)< z^Winj_6b(jHP|sbNqtTcCeDY{wa8m$^3%gm%~XY4a1=-_RFl3KN!K81;e)#1;7lFN zQtG^`l|Ya#wi+c^^1dX-hwuLA>4WEN2Ic{Xq>5IQ2WXB6EHjaj*UW&ZNmlb*Fpmm9 z+gzS1lB2>K24>)psWs@_bTFR`2v*%CDi96o-xrJ?H6vCkm;?YL?Pwf;Ii}(8XJR;I z0PKh|@#nNd25I;Y{;>P_zLr&}G+v&4^1UCeKDb|}J}2Y-YVV!b@BaKdqpy4|FE3Lk zZnbywo!3s@|40%GmmhTJpN2R%hyUb9r(gfpc)K;-ti+a&o-fAroCxE3^4gc)Y}##X z^Ti)N`o?eG+H9!4e*OLLef!m~z7s|zG-wgLa+a*Dh^nD9O$Iow07r%Q-ff?Jd8)O(x#nzX(%>L5#!ERpbeOi2vh={E`H}n)32;`H09Yf z;X1>c3ULXT4(lAv1W&{yQ92=*NSjjK!FrJQeqv^tB=v3Xw`yR-?dp6qJGgP{pzct0rSVk416)%`Z)_-FxMWUu3Re9(l(?VSqxTEm+>HY4> zC8;#*!py>}caDDU3pC&FE|!#pec7Iz@Yvn{$``ha=DY8`e_Ex?WM)kRE^+#_{j2}l zuZB8oH)}4-kAL=IaNZSBTRyybGiUvczfRAeUo`RTM?ZRg@g)AOgTv$N*VQ^+HW!PJ z{N&pBVC<)}nEFuFLoN&X0*3AR!c9lxx8I5v&z2uO*6n&Gg|1UCy@#4vBJzR2l>4a2 z%DHW~(rZ!gZ-Ywwt9^*r;+TeM$ltGdsts29na#7hkz~@baDV_H{K9v;%p@ zEQ}_Hk}^|B?ONih+iv^*xi8Ae{IGA=WnCyt&%b14viQ!e*A*=?OAt3^?%O|}ON2DKrXZfG}m!r-kHEG#)oAX9iYwgfTMDqJn zDr0^9_~u(*aML}MMRk0fQn&cdyAm7QG#Ybu_TJ-9zW?yyLak?F!gz!mck1bZ+n>*i z(pS@2VR`xJ`Dju(mnVleG@|y^`Z6yTmtXzLuW~0Gq1}d4>Qc(tQp1xQhc~|RN-RPc z9XVIJPy<2x)+h(&B$2vKPy6=lv2Hu`QM%p=xWfCYaK%J3a_r$SJ|15@c(!@+xLt29 zR-1cYx!Z3qih4FaDA%VygX^91D&i#LCp+9Qn05fp);ZsdxL65POV7KV(>*d zy+&2(Lw#}bI4xGEAAbxLg$@rrGf7T^CdRY9cI(#Nciy1cp+LoPHJz)#IjDM-sm(Xm+PrUZk{{-F*G&haXPMP)v5cI7en;<#hi1WP5Va*P~fIz3E5u$-&;Fn8Al)GI7O>T}`fHAHW4MYtB2O zqGA{DqZ#b{6?m4J#K1enj~O8kO#NL8V8XBgH8rftu0Wr|Z}kPkP2m6=nr1a43xnl! zFv0^$=g%+x{y!Tv+HcSLcH68rZc5!Im!Mv`gPc|o~H{N)yeq)?`FG-o%u?IBAXmCxt zee$y(><2#?&xO1>U+>SlW|LEdibzru7+pR(3uT~CWQB-aJU|$@4U}>LEfd598>H&=0L=vK8ZP3hA?&kR1`vPmrcg5@Rdl% z%z!!1AP1A%)5(oH$8K-`2NV$XRJtvxZJSHSVeep8)?X;bzPWg?T{Te3rlWD) zr~HM#@VDROxsdAWk)It%v*ytqXg$o?uU4xsQhW$d8#XDHG0b(cxc}(y{)dC)|Em3c z5k;|E17H`kJ~+vZNQn$2bOqPv&(0t-II_WZyhGR$>(v@~P&Di2pZt^2!>9f7lyWZi zk9Fj7v(lJi*NNIrQ8e)wPj7zx%h%p~EzAzt+~tpd=FC%7Wz*n_99NzL6TP&5^OeJW zg+6}1{HuTU&%XWUJ+s7;o}X{KO?>jSaf!N3_r}}by#3Cvz4i59JGgPLtY+Ku3yRt0 z>;||DaW*A#YKV))>HD9g#cFo_uuEIB>>LBm`&!!0g`j+isn@K1OYG@rD1v{}$fPmhq$QTh%LN$9CSP z^JQFYY@Kbpv2ACRjoG9(YX|uXk)f<;M?%saa(h4pIFDXQ7qYorOPxUTVdkkBlA~qO zoMRVV))Y7WwvU|}kKg#Szqwc}X0t;s$HnNNYvS_pBZD$C3?Y;R0tZ-M`Qoi_e0B2j z>x=dF@ZQVdnp|;t@}!>4y0#@^vM4Es;EQ@}$T=r62}QxK-Yia^eDJf$>|lI!Gp7z= z?2569hO#(){=`#iE>5;*XF~%-o{RB*Q5Ct}Jp1@vM}YVB^eE?c`r4m&(=WH1=gXh{ zmTx|e=MUr4ALO_y_Fjb*HdrZ%U~Hy4|Dg^6*u%7D#~b(9F+yM%AY4o@__DidXHWp` zAnSx|S2fbEbzjh&c|X!sh!!(xrhb?xH2-mCns(m(6M1TynFvsH#pi zXA+Gzo*upR=YNgru`AhCvj>0t15TB)o87rR8pYf#%TegsrS;}uw{P9Jb?^Asf8h(! zx}SaLJJaijFTMO`J(=zwUSpJ}k00b@H*URASBK&7cD^|2x^8~$=Hinl(3X{4QA1=r z4_OTxY|hq1{^FCTar@nu|NPGt8~D?q{!j<=_5asXHW7E(qR8 zk~Npzrpf(QyOnj@)I6njshi8q`Ib^k{hAgh{l!UlvD6?~V_ zuVfq_5J6mNW+C{l-Iy3bM04!(^9PrI{eS%*7iC!%&$t+u2~z6SltY;{&kqly#8NA1J3?X7YTFq3cyb2fq^X)#B8{g~DT0Z5+Z&CZ zfBI>A`Ba~5(i{{Oi8&u~lA>^u)!YrWwMJDz=Fom08HI`_sAq*2BMg@u_ z7)6PqOp}y&5s)tj%A{yfHX)OjWl5G`k+vz(GD#310TAF2M3}(@45nu~cUO1is*`u# zUwG46{;^N>!2VfX)mK$_?frf4yVmpEcj^s0lcOVC=q&GdIt8{ITyhw)(XgrolCX35 z@T~|aOffb@iUGAPC85r;oCJ)aen&P&pl+@S7i>3yh)D}Y&|MUdp$>~hoFA&_mPhC9 z__jZOz~@i=ck>7qPK9Mmp>|p^VgqEA?Et1ycR4K3pKbn5dx~je9_@WhyV&NTD|nNulEshjh+U6K5E1Zep|zWbir>>Pd#fa-wsFvKK&^G z5K}aFKFqqE2X}AB$%zs1jEUJt^e&J)F+kWm@^Ba$8^H&CRX0T6j_n5+~l2dEz)9kK?LZ zL?Z&#A&AS$5+sVUI`1%2MqCW~qD;Aa zjm>wWwxTUi9-_-gC$g9~vq?2MoXrd_9x?V>Xzf~=1xk8 zWE!8o<9Gi%MinM6z?NhNpb69B_D}t_y^Srqy&pnU*xFvPp zWLQH?4QWML#vT*;#cXnLukOI$V<8if`Uw`GhfWg>~?Tr+((v+H%>IxA!ajs)E zUk&zd>Q46P-8a)aw^?NhLa#pW34o@H$&P%KYy$vPckaRjq$!f>Nhj@V?A<+Nk%sO)CYeem;N+yCqfsjHz-Aczbp1Xh&o?({wm z)3@JAj4FkgQmR&hDK2JNC;GP15fQU28??)*sm(h3B;b4W&MiM~ZrZB-Ew$JjRW#KD*nn1B)}B(jPO5+f=gO=PUKnO2f@ zkd2s(b!T_)MLFn-22`XpkTJqu>P0ht5CR3UfGj{DQe6HH;XGZ$-6N7b{MDZv>88B$ z9BX5AM<_EuN(GTbikJxmB{3MVlu2~TsFVa%W>nd%X36{H+Vi7__R8~OZPw{#<;M8@ z?EHM*ohki+s1& zoT?y%CXXJxuOejS<{owW(pGI<`MQeLB3APPB}C3IUCy>Il}$6aaeaAuTHiZU9(-My zY}OTLOrez=fAL#8-}^Fjy#yUm3>gVYjJ6xS;?n-v_&&5N#mQ((S>b$an^~EwIs{5} zuhU!CIgsnE_>^F?p4DG~vpUY=!H#@^{{ zfLI4Nw^?CwQYsg%m7tG)v~xhVP@1mXyfK}vHU>rHMs+rOTjunLPY>^H?q3xjjW%rb zweS8zp=}=@{fj))HqSP8woGT6C|@n6MQ2F5FDU{+N&(k>GLz!TSF*u%xcKw0heCMK zXk0hjY0ao2jVLH#edd9SUk>XA1YR^?=&7ylBhST0x8$eafTvyIkBS5cgb+Xaw+K^x z@2&Rafn&E=oeM*ZfrwpfB1ce&8kHs)cAx!$PcG-jESPt?y{&EU7t_c0jH2Gn%UD*; zhfi##h1oYXfMGxoRJpjep(ZTqC1ZtAp#n$-$sp90vVc(ZHu!eTyMog5A~Kgki4K@cHZKD`Qxh|X7OTw3K-g@k+)>VqKWj!9+tK$z}JAL!l^KRbhZx-~Yi3%ezxMdq^DY5~C z2vMtmo4suqUGnofIOm$h>4Og^<8#y7ZcW*{c>}HW^BMRU7AxyzFdDw_=~r$%dsRoR zRHwVq*}T59w|7ud`NhBY(>SRmBtnYLr@GZjwQXew9UN@C#LH9%trn{V8gj`ck;XNk zz%#V1nR#2)Y2xeG$JN*GpG}fpKo)JM_6~^@X%vjk2}|?=5r7jS2~&!RePAakN|NY< z2T&l2Q;MFW7fGn7bj*l^fXE~vg}^aHPAS9yth@`6BXSZ(9};j3zIJU@Etkv5*{p4J zXJZY!MnF~Wh^X}>PaAsoi+?wVsyiH{m^ih|^CJnZB#;zYm_ci8QgroVNuY_W(ki(M z0Z3)%Cu2}0kuq6^N_YArn+<%kgt!I*K?qS1h+j#nG^I|j7X<6o>g37&vy;bn-uUX# zH-E9)p-!hLN(-n`j3Nx|$XKm0hA5m+8$s(@Ppn-VY|#(ZAqWYq{~!LA=krAYOV*wf zjgr=s6XYax;h}&Fg=qRM4}SIZlfBNX6Rw>X>-XTrJ>erm%eQaLYouIU%*PKu%&h^H zJ@f3#Z{I$a5E8VKw31A~Lr9lC`-yCSH_XN~aqj3erjWh(EV?>2l>wtin{_kCLW!Zm z3>aeaQG}b-a(MZmsaDC(H(H&6oOKU1rRX!2qK7t2>_KK14{BiW!mPdna_bt;-s|J zS`$$WUW-i}gMij5reutbAt0erYTXZ!#Bu$13*bZ4Sr$U#=$g7tZA`w249>S;dya(Ovqc6p~@$C$iGy7;dJ5RU6B@H+0iu4tno^3Pd`A>Uj+WUu-x8F?TCRMsVden~3a?q)6SBojf*4Hfp zySfb_=C*@c8*QCyb#7x=0Z9^{l|6PWlGRmPbc(DjLB*XHo}Eq4>hp;k*O@7bogtXK zd*xbOO=fSrb@ImBF=Wb^)OZzQedEGRexBHAD;=B#dOXsxh8fGHgCN2{Ajp6I@p_5i{ryNCi3&;;d@V-lXGfy zzu(*3>hy-AqTi1pq{JN4(-o$YlsI_iSIIZQwK0UMs(drs-QKPi=bkdR3h%!DmGi@UesQk( z?3=&v-;8v<+wX$OsqAUfPcb1;Xp$;2U)KnrjS)m76?{;nV({(q6p*wrz2R2T$pDEZ zatg>X2{TCYEih`6$96S6I%!?#4Y!$)(AYAM)r=qv`kf;0aA<^6a!X~HqbJ}LD`hg! z8LlzlF}C&0tW%7_Kte*2?W^(t1Vk87T|}B;4Hs0BfD8eH`tkqdKLS*M8rR{&bz9}z z)6X@RIjyIiAJHA2TDt!K-HuQ3K_A@&kgC(4`ak{E?|%6c;ds^?ZJoaLfh?P%DCVn0 zwOUe4u?GZc-?_T~LKX~QSpOlgg-@jXrmy7XuYmOru)rZ4?CzS#nCFY4Ite5O=_k^*+n1$Ouj<&0_6NMwY4Hb zvS2b-w}g<<-)bKP8 z4e25ZA!}IO8hZG2HngrxUW}I%LPAjT?KcKOGyT&4^xwaF^ZF+1hxZ?pWsz#HwOXB3 z-OlF3pCCqt;>lwCJAeDi zk}U$q<;`kUDQc+%i^@Y>-9?g#G=-xX$I-k&pRuvkBq(brp49dVdy^KmAAp?*wCj!Ed7$Udp-H;els&2-SC57l}h~V1BnC{u> zQCSoyg`jE{Cj-?gow~MLbb2Z;KscousiQzCWs$Tsj1ZNwPjmhqOaQ5iF8*H2BUfQy@YdeFKT7|l4mepc{VI^pQks$yk z(v~!$)*6zC#0cOWwKcA}(#n{!3~jBH0YV4?Ktvi)jA#KE=%YGIx}eR0AgOg^`L|AW zK6-esf5-p{*SR*l@J&2TgkJpOr|~#kUxnpjApi)F7N`H@Z~b+(s-OMrcc0%sPW7st z99z{=1BjG-vZ`p}Y&@Sn`@25Z*46Qs-{2KX2#PXhq$I)=E6*)A?FzhK+`iZAz5>JU zfXt>UTYs7m%ICF(4jno!3;t5_75W2%uu2r%D(iwe$ZIccxUp`tlY_+hY$bd zYe#QA=w7~(LKs}zo<6wK+sJ3Wd35{1^VzNbmC@w*aCv;LSuJ8?eakVn^|Z6S5f?RC zmG`@KyGo%QiaLID0*?>(U)*O^kk034_hZ`}Ja_fp?GNt%>^lYP0AiHZ2t+6%XNPCE zUb*$)-A6h%3XpwZWu=Dp)U{1pt*XOsybX)6mX`**AiZR-wbB7Dc?W3=J zt^d-^ofocWo4c)-BrcQ8Xi7i|6e1BID2gcp3tEyOq?koe0usiAO5vJrg`ij%fP<@% zz>=L#$8F<^PM5hx0ZxqzacAR7Gd_ZYeNdXRj;0=(zQhP*QZrxQgM$x8_wOOll^3ot zAW0%JV2Rl)n~7g7CTB(2NdPg%EX&&3J$_I#!KLjzBAW$oZ3d~OeyQzCdSq%LtFwFSi4%D`r_A{7QCSO0|4uF zYn?7ks!t#5fKNFQ>xBS*1dN8K6-s>i&!66sKMIPH0EBw_i~qNuC{ts5WpA)QX&xAj zR7+b6pjL)^ogQF2KXbd+c0c|3&prO)7is1(MG#EBB2cNYd14>Eff!=K*oaFfZ@ypb z4NRx|i)wgQ&cJ$QkrZ>&zIA=xXm&E`LiT8_iQXfkGFC$1Ms;b}3H(!3n+V-2z>G>Cb;(ebCemS z5J7vl)I@+PwJS;98k^-d1{P(Tdes>WKk?bCz3!k}mU)q(vO*{zF}A_iO%pdR-$00| zSvAgg%Nz-9Q3ThLQ4$j=k{Bs-p(R8Ol(R63N+BSU2*tp)U-Z_FE?E1D&3Fz*oq;d2BnM$Xlo+KqqiQs{)@ly{Xg*C8%5sT z*yNOYL#dW(KF{vGar^v1@9MRygZ-_YPu%3jd*|4v!QP&A!ooy(ig+Og#TX$WImE=LUwiZH z;p1CB^w~;j5`cCIs*p&G0aaA0AjO)Lphlz=8CV1%v@HuGU=l{8lq7neVx;Kn<@|Vj z_SJ8USME(~P$B#~zyIaS&khYbjUd``@Mubrgo26J+6x%%UPUFYnjR4AqJxCO0wR)x zA+jWZsEscALm*9@(9|ZgHtXzP+FtXY*sU0~E;^)5j4Aj=kr`}WD!cs;zxgFw79qyW z7BM(&H4=v4iL8M5w!%!2YK&B(dix04nR7PG%GV8dM4sMjr%1YQ?KK z+T1is1@9?giXMPN^agF`;97BMRPJtrvWkpSnKoMKEGxR5Uhmys`+C0ey-sGLFhWeq zWI1Wj%EqQSeDLVO-48zdBcDJ1@Lh??SgVajE4!C2pB_K<-!Rb1Tr@JItCPS$2VF`@vG09lh|{c>3?s;X@gD`kk265tS; z#lo6QSSba-el=T8o;+fP{$MjNO>~VgfoND`yOTtKm{5%^U%kIk}huN5_eY6e?1t z2q{etCm0%&myDn&7jdXf45)3t9E|cZ%gg?1b|gM(lO;$3np5Jy${Iivr3DF)6&gS# zDH;WBHIv|&JrXC}>|OqxaJmqWtxZMi_3j0|69GW|*pL4uym*jbgc`oBZxKNxLBn9y zuZWKnzaNDlo?aR*P;lrMfB8p$&*Jn+<=a`)9?#ESdg0lF&8_O>%rH!kPnk?+3Ta~P zrp;>68SX~s-SpHqtB|6$ijX?}f$dpil&c#=pvb|;wy6kcYkyB;9-U`S90Ln;Vr1>w zHt+UvBPW~N?hq0SyTnmqh%UIMe(>72E?>EdOqfClQBW}nk~Vo(6eSa2lxnu>bQBS} zAe~N$mQEiXLdX`0s~V~m*A=%RE$h%G9W*%hN3&In@WF$}3C*qNZ-94qZ$AJ6o3WR` z$fS`OVu*xBmDy;g96vdpx)8*4jZz{hupx}mYXo6W3VIvE;2Qu6zG{4Y@sIwgllNZl z_6D(SV~PSXAp=Pwb|J)7<(%(d-en=?uv(0*=?DrZB8WMd6j>2U@F+35Hbhx}`~ecD z5LsMP%_k==)bqvat8Y&#!QcOx-uHcC=i{$j9}PPMoMNL>USw!CHc{mlW@ls82&mv% zO;pb(kX&at5=o?V@b&Wa$>MCHEkImdj3xovy4J>W^lr5{eDctTioOoXB?P^hBS#&8&VowQuVL58Xr?R0~W)3Z5vGhdFYK%tG} z$r(zSfE;@lUGDU%#bv@}3=!!UzVK_y)#5upe(8IE@RbEN{Z5`pxy9`4@%a4RRR-jf z14Gi=@(iO+=X9~Ep;R1|*cg3=(uglIX(No!&a_TC%Ky7?yg+h_lzyI^ONOt+)k%JS@cdoIz_hg>Zf3{ z?;r$-7Rblcw2d%JjAxU{VgbMR`-aB$Eljvv3dbM+Zg8wdrb7*pUFv%IG?rMk9RHW>B?n>($C z3kVOO(Wvtwpl<65j0WVr8!sQ;zs)gnK+pzBd*7(6LlzT=Eplawm;^$ttVUh3YlKN+ zbnPnANeWYC1{dhVixWORJ?qfgSFV2SKlzWI-f=(rOn>x5SMdLH&cUZkF?f1m5WM&T zC`_yW`M>Lep6lq!_DesKLW-|^`Wzx9T)IJ~@HoiAJ!C31gzIDIl*j#oju zqzwobMaSB**V_aEjagbnaN6WH)GdJ31~XfrRRGMw3{e16@PKHPWfoLQ>5S)XSj_T4 z3B5vPnJI>*cGU;>+uQFq4<48Md$)e%2L{jVWxM_P>7;F11R_PY(13ti@7>&OSM$cT zIx~c7Ro54G}=Cs@sppzy8(L8}GRX$L`^g)UC`a zp4Tv&r*U)s{+;=QV~*V2-i#rH#C0{}P`S4L;LiESU+nMqW%tsROFLVg{!nR<6l3&) zYI$v@)UKrs56 zLE37Wm4mz-l45HuX-kT-ZV4d32?0?^q3FD9>lKGK(}1M3H5v@B&7hH$HcA_tWy}Fs z*w>s`7%{9kxbe|(GnJHUE^vp(Wq_)IU}8o&T>vG$TA zD0ty4Lc9=X7!V-zul=K+%$LWbZn>Fdn;G@Hy%NJWPbg80-fRva0%1x#8KDMSFR6vu>!L})Svf}o8yN-;4f z!`PlqG-4VrmtTEz^387=*OK!pQfgvUsk6J$y}5t&lP_ew?)bxp+N#6}6rd2NCZ?bW z5d320SmAs+YbstW>bmxeCbU4S#7z_@(!{U=0DuI72r){_KV77Udl?4%|7|FnBZ?`NuK%Bx#Sd`JIln5fxY%;FqW7pP2w`(jCk+CMa znp0F704=EuP_!|iXgJz_a__y&W;*MVf&?6!S{aHl3;wLiHhWB z{`UW_dh)@h&KdmHs3TISWNN?M+ZulJ{dfIJCg&#y2dUc~=a*jzkY3h z*xiIA*64cGkVXI-qBE$JsMs`=cWhY@0Yi)eNyKCjV^o>tz&eMuUI{f@rBiHm1J#=! zqOi_Pf7p}U`nI9Q#ruzN{3w0=WpinNHJkOX55dG7@-_-70Ih7dY-g>DOu2>VT@~B9 z6;zyR7c-ZP0}Q~4!6QWGwKAI;C1DBTu-Go)?rf~yezYl(*`U&yvINoj1ej90PK707OoE7Y)nhsT z`7gy$UfjACE!LCee&1{s-K(4ZtVhW$0rZojN7^WDd%zSy{A}6Xy`i#P6(Q>6 z8w5!lFa=UdSO8^fe;-&rt!^F{LFSDH_3C2NH# zK}eiZQ={`}yJcP=v}+PYndJ!rh!Tj3h*b!|smuV2Epk}TZAlE7L@gX>m1Y2FIRPcj zlA?+P8pyJ!oB7`J+pVuW;lT^fzW(*!(0P7zG%d33;MGxmybx4=o&W$myC8WV>qYy^ zKl`Oy7BN9LD`LBHO}n#yU~H^b3lK>`Jj619azP}ys@A};teQvX^vo73PJyE(=?+q; zfa}$giC7YVtC&<2znCntVQQavOis6Y}b15$;yu~~+wqW4Ox;FpRlia&q&e(-Mp z`b{7W3`~&xGS9Q!YtLDmlgWspU(RNenIbH@-QYAc3Ns?9tW2R%y6g@Hi<2d%#*kr- z#GHaxMjI=nv$(b+a{ypPCb$Ob6?H~B@5Z>!0ev*qk&8+%^HXB^MdWjB@Pc(R^n#Ri zA){Vb$`n9aBYFiDpsW`Riquzr=Kry;+Wz&Om7C9JyjY&h7XcNpsGL-pWt@yUYYuic zx3;?V;nba;Ub?jB=ZmB1cyBbi`TXoNyy2OyD=v$wfR-z-vln|J?UDH#MReGBEK)ChHuCa@yZ^UYd zky*E%*MMzC41wp%YHN4<_{khHXj2LdK$Ilak}3cci~wGs1c@S@n`L=DpVs5y*4EL{ z<2Szbbs_T3r35}K5tH7qTl;&{hi9w9n3lb|R$<## z#uoE=ExrknViZYP3gl9#Ahp0GI!H<)v<{ab=uGu`c;mWPxnq=DFTI>%I6t4r+NKQ{ zgBXp?YSrs^&d0OpW3v(wt#lq;+_-#sQa8-W0SHnM!~(8^K7u!*VP^ph74$Y=FY3Bm=8VNGJ%LQe+eq4XLypV~Utu zS_AQc5>nC%0e5d+x&Fdc1g9X8Rst9k3o76geB*sxFB+Nq?yzr1JERSwB4rUoASxhE z9sr4mV+$PES14@qUeVt$CL@I@rQ{+RYqFe^c;C3yLc9l+Rf|QZ+qYIDk~KL15oH7_ zF)$L5jxo-st4>j*lt?2GXl=DIsI<~LHWfe$-YHJJnAeM%H=mDa&JGWM{uh4rv)}h4 z%-?2M0jY~mKaz-OfT!s-r1i5O*9jltr(mIr%s)!H5Xlf|t^e8o@Dtzo#edi(Wv%V@ zyP;k6i@b)A71>MAf9leWXF#XP+mBX{j?pcWDmI_Jes=fK>fw<;Jh7c&Z2kE7a8nHv zr{H571S3F!9FYp6P>F_Ew^^R2!~r=M0z?-gAYzIvAu%g93Mp|i+W6L?F)2ogo?Gv{ z58kD^hQ!n5A{bj_3g_{?uf6Y zTb&I?22@6qv(>wgPnH58X?vr~kn%#?ez2uS#ZBO%(>r`}ZmeR4;DK3;1@9rt=+VQ& zf1Y_=J8~HbdIEp%$B_#nv4WVYor8;GOeRvckf^^59fC#=MT^Q zvTc@4s@(i|5$mS%5e;>0Ht6*)?QL4aCJ(m9U_^lK-MzQ|^snz)q}JwBL`9?s7+r#@ zhIWZcXOW|b^gF$BGQp=?-wjAK&!e<2}HmLKm{TY1)^t@DKb>A zR+#CHOZM^Dw-pow-3WwW5SDelj{0g%-F`n;*xT7|R&$O~5-5_QEJA48#L;uKz_pCW zryMVJUVu&?Tv5}=UM0E$ym+8`uFyqwRq%?J^-GPXk|Z|jAtrcJxZi=noq$un*3 z^yE+hWtr6)wNe1gDWnix>ta(U7k%9I#mGAc*U%R3`0V!2{i}_QJ-ab1%Fe^L-#fc=WJHq^?wZrXqny^2HlIQa zF{H$;Te!A%l{aOXI4Xu1+aP`!+~Mhy@q8TGu$ayJ9VD?SIf4*`0gWOOj?5fg+bkE+ z@#6fXn$DKXCL~?%^`~`s_x2$I8Kl~!CP1#K+bxYnjTVHpQZe$RS{y$cLkQ7s*6a@gW%&pCp#CE&v=q?4En+`Lu^YIV@m;KUOWd{R?GTiR^x=Kkxh=>?sB8v!cbiTa& zu^T#Z8JH29njuNT^ztA36E}YUzq$4Cm-+6!<@wzE#EDTU z9~co_LzSsnwX0PNM1fsk@_x0P)u-o8+1>cmcYdPf=zNoT$#szx2;3lL))Z$?9-ck; zAUTenQwpdvA}fr-emPs7pB<0SAG@ZiYrk5o>gk!bJ&D}bbyHQSg@CNdfpiQ`*mFve z6X~KixqXTr{baJV+t=XIO%IC5o=mE5zVYGj z`$K=aHy8oxry(AGnu>cG2mSU1_an^V#cDb}-N#)N!BFYjU;3q={;&S}YPM1)_KIPz zm-V`Np4r{qOQWK5_Wq&q4lqx3Gpy76!^5<6)!nqc`%Gqv^T`anSW)5^kl=9ks58i| zEvzZdmnR`6tI&3{%2)kowoKV`Tw6sh`02^2e`$NUTrJPfjm<&Qa?yn4(UtrXm>#)0 zNJye21Yfz(vTMV9I%x$W8oNEPwv&97>e@|xGfla%0hB4tw3#1Gp6uAGvD0-~`TEy> zlc%0oi(x_voYo0JjVggKMqvW2S_vM~YI0_^7D$W3!{VkwMF7T^e+ zAQ|-0efG1TI6pZHUcj<|1Wlo-N4tH$athPc-O=5%>FK!L+Y8AhrBNBy9<7}qU% z5K^#Sg|1&OF@jM5m?G#D!=-ELv`u~m4p|{qz!0HqfPr2}fAN1TH%1$Se(pKO zNI)#Y!b+h}VhkKUoDXgeH#fJi$R6B&y=fkAA8a3<%V$6P%HGy4YGrpWAGdLuI6FCt z%ZGzo&j(KtI)ja^&{U^Khedx-hO%BRRYu+ZMsy3esvkUf07yliIlt-@Sl8Iz`LMLc zc1@P$nv4s}OtG(L%9e^^+3n^1E(^J)F7gbMXU0rh4YE2phqhhTZK&JePznfjw8fya zcOz|H(nU{$aZUWWfA*_If0XA1006|N1ATbiZ7Y|RCi$ybE+<5+Gwo$A?D0|%)f*&vQ4P7%W5(~og_MWt5D$W+G4O0r~yeLEKV~f5Hbv2((EAJET4*J`>tK-vlvdB!4^*YPC-rl|h z6ja&Etmp@6GH=eWWuWlQFMp#uj|Cc|#KnY4)B5nIlq5-`m*{ zVimCqmIMl&FsQo1;bassVkt%FWc9EBK?LIQ$~tGKu?x&bd-q?VZyL#`zW zwN1)3b2@3J6RFxjEW|{JQB)#L9739$ITSLc`|dk$eB)ay58ZG5!^i*OzxV3i{uK~1 zx#@2mj8Bh`r>90)6WZ0i`*!Pc)t{)*?jZ<$(g@$ z6%()`y|K9il3XM|uWAuRYGZ4NK;8#P%giXiD(h@2LgCu`h}w|KD_4E%*S@}?_1T$- zlB__nkYOf0O}&2VXfot{#gLs(rnm2&edl+5D$BdT1hl5NDZuy?<%WPD%o>0Jl&mS| zYaGzUO<-LNKmZ}a2XB1qpZs6`W}y>Ay1BP0veEi#wrsTOY=PNA1*fYiK;9b`-Ol|t z-?ItJgS}<7TummSuE|OsRA*!8d|NLYLuCpp1SDJZcDs8AL%;OXwziqA$5TI@lj-Ky zu0rc$h<>$5Q8H^$tK_)Y+lg*Ey?xrLyT4HYcTaCBtSxwBxw*?>xlpn5iqC$}?|9+W zNm1BYyxZC*E?e~j~o$}I-M`er6t-TxV$a}>)c1VnKl^82+r9kq!$ zTv|-Vu2~U6HTRf7u`xhIPFT+u%ux~`X146!`o53feg9i0Z{F`>vA4UcGc;MD2^WjH zSuQuO>}K1;JMVpftJtB{N&AEfAifhz12>qC@8{Ki2@^t z#2_GK4I)NnB1EN{5EZIAG=ZgM7ZAwktgkk%?A|~6Q11p(tP4m0NT7(6=DLO`kk+a% zf+9m>XlpdQ`)K*_*w0TPO+gW6imXvU2pm84Jy$35@Y>fO-+udyZQExGN6hQPyx2QnxF<$B#bCY;*z8Bn9ok1y!*}9zWj}EpqHx$o8SL^ z-?6i^H@Wu#r(pU6+v_K#I%N-1AR^Rec6yl50kWiAy8>$l z9qjkYPQRl$5g}$4l}$+yl(Ct%7Ht<*u55XD|ATLS;pZSiF(_20uWT8Cl(xg&Yb-ip z5kx(@d-!Yr;wus2@BX*`_)9N;*YltHPGw42W6qJ}BFx5X0e}Wj7b4&bv&%aFlK@Fj z5M+G!y~n@wk6*a4>za*t`6?L=5FfsKe|CO8vSnH(#}vE`!R=kTgb>|$W;@u-9k|Lf z1m?@HzN|;X>TJ$|XNvwH!BXFDA2Gu3U0k&s~0e|IX~KccVzA^3mmkLWvhwR|!%p zUKM$vY#5AozVXk$#4E3q!gYBG%-Z_^#t>5CNQx9vQVI}rooSP6gR|9?Q4r9jww{_GN2TIKm^bhG(cjIwS7uJ2#7A0mMr3`wk(v%6ePA?iRUm6;55V_ zUO`mQhLr8}U-;as`>#HKaO+xsYlAb*nO!^WL@6>BDT4Ra;iG%M`RjuDY%4N?VtYrZ~o>x4G8>f`7e#HJbP_> z?^d3djBCf&I@zFrSqsQ|$SJ^x1c-tp0&B#>?BwY0|Ly;L&!%DCE4%%TjY3I$_~40n z+fjwK1JzOOe3th{nQIpHS*8cuH?LLgS(pVB6I^7QK}<*Q-VMt-#Ck9q*3-Glj43<1 zR}`HM&r1Nz^M12xo7VTX`dDaQH7I&9u2Trw2ojI|7+GqapJZTdwA zrJ&_`vwY*jMIFEvl2YT_HhPA9e7pqKP3r(z*X_aOE5G@L*T^eljE_#O9b7`FNh`CS z-)Kchm{?GNtTsqVLzWLZrBKU}Wmzpio6>XvSZ5dD0Hpy?cK5CKt)IbV89F1 z&iBeeQ;!7!H98Rh@G+r=tsY&y+Qm37mEGOJX$1?G&|n^+Qvx_Z0;?fQ2qfw04Or9# zqJsrE3Nt80A^0-S7j3O9W(Ax(X&Hc^PU-q5p8Js>{k<=K>Luu9paoUN0x1SRJ&sL% zel|XPd^kNlTO1zGs_{UDex6U4Y2(J#gXcfB{nE2~V_SgMzLP|{ckTJ#^Y8!VPyV)V ze*KsJ=`a72FWi0ot>5u)|J$1{yix!N5=IBrvRzISOV-_3P4Bkz`CxY>(TdU_(CLrX zA3CK#qL0j-!LDD;vQB}dnPXOTRnZ{K?Jo5g$Y^andPZoM?v-n~%Wr36SCISOh-k@c2E z7;#+!R>u$T{da%$FON0`OHoHhr{lBtcMEfEwA1fxR*Pw0_s<@V6G}Pk4SW5w!*=)P zbDe%KjVGBM2`wST?w~t3*qWW3rU2la04*zTm2TVU1FN=fn+8x5=n%wtAXKZW>gQck z=H+0+*X?qgvaHC9?s7U~-^@-bj_iDssj~H4HPcKw{Z4=K;ISg9!J$?mF##ol#rd-F zQ(_DuVX}p#Y*-#09r~5i7iuSpAbJh80T2LVY=YnzC?qjTgaO2HN_EHz>yj7(ol#O5 zD`}fW^0E%cBCR{O^5oHZxpO74fM8-^0>!8@D2log6t2+}i9E zxge*#?`Z7s-o0Ijgr02Exf?C4gvcoU244 zYGtBGJ|t%ED@tA|6TJhi7zjXvfU$i>tt52^8>FqWnMj^>`e+O?i^SP@Qglaeyng3& zN@S%+%H~;O!PsJG5g~|~j8Ep1vrm5Z2m6}`0uk3|{>jO^Kw8$XQUSb>htc@>^zZ!n zKWPe7S%<5JAnn@j_3bM~PtPa5K6xUwb1@bhgZ;}_kMG^T@yQp)C+FLeRqZmYd_7sY zdJZ6Vu+iPxT(xaG8Ak-IjY6|pwpniWuI?25;{4>an)s%UJ~he5I=Y?9qrB|aGhffA z-EN-QVzF4Q3G7+77v}A(o!TM~-fZvhZ+0?Yw{1w{^YZ|eKx)6L9_PJHM%yfB3O%R- zZ5Co%k5`IBVcxqj96uf#uMIK)r5K9LLKKr5g(}aw+UUAoMM)yUnh;T;5maE4&TO@; zVrUX12JUQj%s@R{Jc3O@y@m*bsQBmq#uqyMt-to?J}In{023IC0C4ThF#&458i(aflJ5M0-}M6@d*-Hd%O|&QpC2FB(HT{4j5eNs`MJTB z&Ech8mFLP>*nE!M6KzX0DybYGVshZBFgvYhP7&v$zRpWv03zR3>^*q5I=XK=8{M5v zJ=_E$4#Cx{X8d@5{77M^duhMFwPibfZWnI4s4EYOQN-Gug%N=e5~S#t5E>Ct;=Nm_ zwGEa+3SjaamD0A<<%m=Um;o9W+rx(+zVod&E?<8>E3$gkCeO#S)z0?LPyAOub2y0| z4aUN!UcPbT`i%`zHdnp%FxkALT9H}|ew>;W!hV8Q@`%t8o=tMT~%^MC$p zJKMvIxXdy|c4u?nFRHw2hdYDg`|qb15Xp850QK{OLU;8E^A}GDip0+EO^*5u| z90LL58Hk1`boA)0Yqx&Tm~ORd&_D{H6%fg6I`OT{TXX`^!0_to^TQ9n9wct`pqImZ36GCq)qvHY6odqdB+nEkF_tWdj|>2W7$TG|x%wFZ&DJF%0tJC`I z(W7sC%`ckC;UOAbbo1@~%R0++3@48se{lN)lVvY|>SKhQ{Ow2L^WG*DrLjtDr3S-| z-2(;rYBG8KH@^7mU%P$(#MP0m-`xBYKl*!ny@DkoS)}BfMo5&(QVhVZZE7TmK}5vO zCps?-6rwX!N>Tuo0cuiNTrIY?_HR9xMwhOIq^7g?eNb7k@y-VimdjWeummnL<>u)0 z?EZ4{{K38yMY)x6w1LEuy!XzVpBeVF?E#Vo5acLNaS;g8)XRVPxBmC>$vpyf^~N(B z*;b{_tg_v$Znc~~I-gin{ezvw;hE`{7zp#cQ*7AY-qz*p-q+s1+{Pfb-;HE!rl7>w z21*h_pp*+C8e==U9#6;;fVP8OPTq$AAj%ZJ_5nnzPG(|?aCWljbV(oqh;P!}H{XF0 zx33S}4NEjIf)m&L3JEjKQ*;BtJ<%m89c7Fb0u1}(C`hX>=VZ%lXKbM+xz7AJ^RY5 zFWtQLVzIlcyB*P*Q87valMo3VNdhRqufp``{KF5HtJT|I{c0WsC4jHzX+vuE;54>v{7&F9tm;>o?Y zqL0hff_!Qg?yXbz)!Xyg{D1tb|LI>L3~p5;1yU+W48GD@yHJJXbY#||log#h=MWb~ zmJ26YPw_#784(jlo8=;`NmW&2Ot10rwb$+?f!qKJ3<^z%_a8nkboOXE3&T-gPi$5i z+vC`-mg(W0_nv+EGt8(#1Qa2sb?!e@(|`4M{>C)}+09$k(krI|)}%IqcWtxiY;T4! zUVrs!wKyAXUO9UBL}hx=85NY-j32yz*RNJ#8nn);^JCWf%5yI{S`m@dsl9gT#Uy02FAUV2MB|N#xYFt9f4Z+j^xnZC}|vI(jfW z_r7+W%(TI^wJ1^{$$T-vm2R7aOgguTIXV`OSz(8xQSdZdo@!ODS((aW5(Xj#lsGV^ zSo;W^=~75iOrS8ay1ak23VyMuk+Kk?5?~Xx$qeYp_}m9B`XqovqJV(pAN-xa0xDb6 zmv2hwvDt7k^|oYDd^>5F=mAcDIFc&_47COu3bHO^dNCuOppKN&;GvwNnywh zaAef9xgjhPj$zh76ChJS0a^h;a0{;qA%F;e{G}IuSs6h5=a4;Ev@c!-ht?gn_Tz>Tx zTXf1!+26TZbURtEBPoQ|SM%BN?YAC%@YuieUPqh#8_$|S-wp;Fmv=9H{9}Sz0DdS$ z-}saBllR_!XL>#kQMy}OrW@VtEVK;@DzFrqBSU9tC*tF zc58osQ7>1sN`oMQ(FjD$(xz2D=-rQ}unm?xD6)lUYnY{JeN5s#B!QG5F%aRrmbS&k zQYH)N_tobwR?wz7z2Y&_mBMHKlJfWf86ADa(w#Xo3~fX6(_$sTdj^K0GUYezHP!(YrA`CYvQ>49HFK^xacsA&YF^C3*Av#74!0TETSF>vR7=j}N=NgKu_uu^bs;#$1 zR|XrKy0A(l?{$^2rrbr9DYTRo%(AMR`S~e>3eG=y^k~_JfA;fVp3T}qlO$F|-OXO! z9T;nr*8O4cVCVY!o`i&XmID?2jolym?LQ2p^+imSFa`J1Kk+yG$*FdH`C6~r?`Vpr zcOT>`uj`;dEhLSGTl1>1Wq*8n8k=l+JgNCSH-*mg(f;1?-6y8g@e;FMk1(}$>k*rJ zVy%rqyrj#|JtOBQi^nHADMBGltGkbFOxb4H1{RYMPQ$bn<2Eks`AKa_H=!k!1&BqK z`^Ndm)x2JF$eaN-gt%M_Dnl$cU#0EB}V zU`PqV1zl2VFHKa=r>21_!A=em1Nan#b(sLb1p!zoLaiVrk(AmxCBY;t0$L%6l%>i6 zp1&z?ywA=<6aa=)0Vck6ZS#Nm7ycJ}SN3$?d+RH|`d|L_|NGe)Ck>FGt6+bp|NM(L zZ@qZ)nU|j1xVE!#=^*7@RF;)ZK)^Ag5@5Q39wLnznF#jSv#A}9^YTQb6yrWy85#16{_qABxHoObi23N)mb|| z^KKzhHO}on`{L2P2Peme&MmLqe93gXV1&ttKuVx<4I)Si*e{kdYlqAEv<~6dzW9xY zk6LTN*DQ$E;IQZeAfd80^UGyBSmk*?#(=1zj+RngO+#d3Q3DH*NOJ$^Z~l$;(Sxq1 zoHEib^w{9JuRTfu>*3YN;)%=<7`PY8)XMWmt`eI8W z4t`F63V~Ctu}G0aY?&TxNwe0cWhfBo~b#kp_d(c#I-y}Mmq z>do#sfgUEq2XbskocgZRc<^-S- zl?G-cB`CrXfFMRLGZh6O;pLI$tL<;Ri{c?6v@U)A`(FOD|G}Rb?i~O!h^c4QpjYl+ z)~tKiZ|r~ed%yd+S3a2yH=(ei6axhy0lJ8UfkZR}LJ$CuBwci0$pSzkBw>QUsAWyf zK?DIoLJ4bs2MCDHL}ds;6a$FpT#t6mV6(V}C}}&U=H&6&5^o3>fb#pFm9LAxd>^g1tv1%Od$rHY;1-ADHxEnM@? z`**(e)^s>TEi_xQi;z>HyvB@GC|;rI*x{L*Yu z>TXlJy{oqzFJ#$nZ(f_tmxsr*^V9KSF^kSAG|ceYmtW&3Y)r1zc5nFNwVe;X`jzc# zFNAhAIXd3j->0oEcpKO)7LVqWdbGJ0l1HQrbu+C@C$9o7e0cc&2jBA}zo*W`j)t)c z?USkQ4*I>}&I?zigd#7tH@BJjOaJ(vhI#1ZJ;0#BP?5zLlon&mYFQ`tJ_TW6rIqri zB_G%{7ZpNUpKVBi)^@*V=BYLYNI^0T(j9boC0Wl3acUXBv!V!`gfVHORg7V|tW3vb zS-~QpNh{LUHXOxLl4fHtj8&XsjS861DitLvq8Qi(Q5M*XCkzhS2vwby4K6%H5d~UE zd}O1+c>zQsQ2Ij0OoZApiEUda2oiu4#F)?+0MVxZ>c{u)Ji34H3bd_mLs% zBOL`b$eNRY0)Whnnjioq1q_jx=)xT#BJ7_+VihAI5`Y5D<)!Q8-c@i-vzV{O0GB6 zUjKjny@$X0TB);)26ddAK6=QSO<|6nyc0wnA08(#4N1r-W2;atL&XR-v5O($>i7#^ zzP!8p!++|JEe{_$XiT0}-dz6tXHMVv^>${8Ze|7#6`k6b_pkT% zMo}WCRs>y&!O6-mJBP=YKk;HY8kAjQgl~QPnd-^1sm**m3ktaLMA0(@mNrCfb&AZ8 zI$19eWZgj$A(dieKx7dOl5cdczIfyO_Wkl~8iNrLpJHq=>nO|=G=jwCMn`A;D0VVE z(}gt4Dy2xuE|!xb>nYM%S^Bo_kNPSv1Ho!CpFVkFO0o%qFoU$nHd6^ffC<0{2oa)} zSp&-&TnlvojsO5l7hEePK~fNewT2*oBuJvDKmC1w^!4BPx$)6MApig`V3|?S zSQ?+49PHxpTz=xe_)D*T$H!A%Bp_DnTm*)qSKRCsB7!O)0MJuS(8WzzPy-19Xl^h% zXcl2P4Q8p{^sBN`wzbG6^dqDouZ+Q?M?5UARdoT#?zIUGDf9I zHEnW0%4#%NA|x%CdcPbo*X^@x$g!p&L(%yk58g{!}fdic=7Pgoo2a|7}W0NX&dyT`L(&mMpC{^Q51)uL;xCGA6W%qd0!o%aT+?-%E@m9NTfCoZKoS?VR4d&n!k;AVE%~Ei1((_4*sT&)hIsj*2gv8%@)oSNHGVKe_ve8zvnQF?t_j z%h?D}r6A3sX{H=QN=5<;X~k{QnJo&{Gz&p;t;B%KS{4no0liT0DX{|NRV{6h=tUV| z20_R)LK0F+fKZ^RR-3ne*C%p#_v^p%=)Jea5CQm*vdp&iD$C5)(EY_f`vcFv{9?-b ztTOm_Bw}o+Z8>mze7Bv9*)`>0vuP@~SokRY;f_#PO(*W8 zS)L!~TYBf#D_OUbz-yZU;M%If!AnBuY;1Hk6}pHq&X4_kK7RaYc{ZKhz1vRagKMLm zYcF>9w^f$SpWMe)J2^RLt2eJ*8SGv$y>8a+NvfFC*`s@R-gzfKxbd66_CMINc;S`j zu3y>S-QCrgL;yGeYEFK9^kBHP3!sIFG$K&m>0P>V6&U z3$D$yS*P(5CnBhqE3>)D!ba!8r@hOUQ%Xo$-}$+Jr3g@>Fm;DIK;6H3aC&}x`r%pd zlu{t(a(lFeG_M*EL6dieWqaHv*J_h5tA(rKFM!w1KqX+HHMPRM0(mPrX8-Qn_hC5)meq2# zxi^|G7OTa1YTCu3?(YsZHanGHorKfMr#vH$I9=7zD+gFrQn#}5*aWO1#z-k8k)#Bs z3pj7hFlQ4Z8GrzZL}iGHl|oKJfM5T|e_`v!$G_`$|B=&2|7+(UG8DNIQ7%OaT$IJ{ z_#Hp2yS=0f!S$&|0TN%d`*^KyP@%?lo))t-8@JO5v4pk`!K2ol(PnmVS@kx1%A{!( zAp-aqy<&Z~xVxO44z4`k-P|jNU9d(K9Z*&XKoX)BML>wrF&YA3@Me!YH(rD&Zgx^1 zpVjl};`s6Go#WUBkzj1UJh-KMRtP62XT^Nk-veMZdgj%^i$D0x_p|EkoF4zjU;WY> zzx1X1nTq~_S3IwGQuJhCP$A$Q6E&&z|WH-6x^7azQHZ&c(x zYo|-+qc4ln3P0t~5e~HYSKd2&qbEi`l3d^aq>A52x3k zdv<*HgJ(bW^3F@oJ%0b)qTj7_+`oFc;q<}#@4HsbD&H##YcTofTwrn8?y%e6uO^dv zIX@bo#?(Msojf}1cJ<`cXSoqlfFuePizbbr7mGQPMh%pt?DaEL#YW!DntF0#P-Bv; zQ~D4ez5jmVuv)nJqDhj1t2c|C^QHo8R-qbg=tNN0^XQ~W=gax(`H#J*7~X#O?rgf+ zF7oJ{D)Xg_TI*6H_f;E0IVcCiGRq2H=sU-cjnRu~&5X5|s+GBe;FV7xF)7e41Oy}! z7KlOG#?+-FfQ-Qy2mnd}C}t5t0FlS{A3u5c@EgDU(}Ic!QMhe5D?JL%mi|Zo#Gfoj zqi72u0suw@0D_7nB1A|vOwQf?2h&Hl!(!Fh-f8M;`s64$XH7rb>J`Hcp3Uo7<=vZ$ zS>JR?tAN$_le)#rp z{>EGHec0AjN=Z_a&}cNpU{nmvnrlL9|Cu-~29wXNy?%3hpk=u_ZYmCwaVpXA&>h}9nH`Te_+TJ`n z9_Lve6Ni)x;Lg^i`C`7PDS5xSyA|i>&AdStA$2^N#M^M|%FeJqI6pk=Y;+&q`>)PK?2e;pN zN0WZ$)2|*q`4yuJO$6+jlQx=#`=gHP6sguRwvDgr`3f@XjyfhUa+~Km?{1BfG$#)p zrgnaIzGy3!EH_1&*wi6}=!mm!p*y=8p|HS{^Em1# zBheTL0T3Yu1&M_K5j23wv@s~0yh{Q?h@_#dlXLt-pZ}4oFMTc*Ls3R>4Lsm=vPQM@ z@Zj$G>tCCnp9#n98#l{q!zb^)|MoY&3Hj*SbI%`q?3K~=Ye<XP()-ai!eb zDmORn_P*{9fs-mU2!XN}5E2$x_cxUmL}bbM2!va@1UnzwFFObOSHA0e&kR9It+oAj zK4sS!+f}C2NQs#MSOi3v69a0ku3x=6fAVCsy^~cf4>o$EozuEvp+ccmHpHYfGD>9U zoJSZ^*4e&v^P&g|s27XMttypb*%!Bn&<>2n<6aVa35ceD9rK{OR`IQFp7`+1n1J z5AWW2c=yg=cjt$G^xqxadNteKVpXo^_X0|xFd(msuc#OZgaja>AtVsO%nAU)+E~1a zoU%R2fvA~^TLMG?2-QjtH`$xscE9KrZCxGT{{U~lFG}q`d#l_Uf$4xLz-9pUqRvAE z0?0`SF(wen<&i))W!svM2HQK3B)S>^v!0$E-ZnaRHgg6^DIjVV0ZA$|NGe8u>B|25 zZ@j+Eo8lTW<;t(3&a<*azz~AU3KCGHqw|Jsj8R)P+}>5Fkq-Bb8Zp> z(1J3X-FW#rhu~bgbahAduQY9Qcsg&-oXK=_b!X7eO=RZjWK7Byol=-7BCz=AkB_I9 zJBRO_AKCsuVOkuYeEH{pX6NOP%@_5Z_ug5qqK^O!(z*c9@8;eGL|iT#;$*cUtJR>h zv%O^rH}`f{i^Ze6k5_Foo{Tp-eJz5Rm}zinr>+|atRWTFB-Tk{VYAS-CL=&0lEv96 zPqqFhh{KMDZb&aQ@vp6~Sk~tqUqXAS~)kYK`)XP=F z(TU2lGNhnQuB{>^5tvaYPIZDdf&+#f7gfQX6&5VbD;=pX*4W>6^WgpMw?8VTd&SNkmIK%Z)kQFEI~ouOA$koBpcc-6nyf)qQm`4$x>wJPMk)tL zE_2?N{G`yvZkbZMcW@BVzIb`LTsF?CVm2=h?mJU53n2k>79k|k4wdbF9!#tKgF|Aq zO?hkWvmGECm$QsVA)Q9HL$;*T3!N}&ao?4QJj~<>c{?_-rZaW~OI1k5@ZqtbG%5qp( z@_nZ=b^S(|-gxWX$?@^#`aF@!ua<4oT`x|rPA@VO2u4VPh$MtujwfNhCX zfAN$5=HD!zKZBm$`0$<`&u+bQcYLsS^6L3}-~Z$N{i@m>4-f9jPUN@b(_uq7|_q%7PJ~01?*Zb~{EAg#_xu(L1w` zj_x9-5Sskp@mD|mcTYe0f2JL1+Ot*dJ9@Q_pDKF3YpEas{rRh1{t7ItR}gipSD{`AX7 zFP^-d?M-tVK$*5n!_mMQorE`CV!-j;{mo)-H6;#RPTMxcot@GC;izf-ZHwUuN##B^t2IICtg5x8$QG4l(WtCJX4FV5 zppY!U_P}b59+y;?SZF>Rst|+)5{m{=q(fkZBuF9xq=ZpKa=?^ifB(*Z^w0kb8qK(C z{;U7}|L*_sfB9F>AD$Eh-~Pit`1n8mkMDi&`)_{#+xNcn{r7(JcXmJejo};bnccg& z+z~-R^J_L%>JI?`vO#STmk2<@f=bW|Sfy5k9wgr&AcS9c1PZ~gs}krn2bus7hyX}# zilaaf2n2}GRajQ48jo(@Iezbh*&A;sqX5dTX)aG+UVrt~^2z72S=gdh!x4}I&Nt{T z$oRUu4FHX$FF*h6|Nejb_adu7ZHzN0B*H1?q9~BG(su9Q@bdII^vlEBcdGGp*>|C5 ztsDXxQ;I;&Xq8sFoF3fz`~Tn{2n#79R6wNu#kaqSOxKIKwN5D)+AtVbsxBV<;>+h} zmnUbJuU?#e@ypL&o}NYLj*oAx=WW~f+L`F{a?|u7*s>HOPflKyMVSD41`&3sHRA0% zJ7JMFtN#4r(rDB8zNl+O6hqKPVWET=HCZ!smD@YK{qgVp&dZC-ezlp+YSfIOU#~Z9 zpPHsWdHE^}WaiOyXW)ziJ*bAm{c-48kvl`5fnpML{Su!9Frq#DT z{&;b{bR|Zg2%xO0-QB&ysnQHWA3${krX)z`kt8~XJN+R@qhR)|HrdC?|{)i`v3gD|Ih!&|KCR+9Nm5A z&VT;D`Cs1uyT40EZ%RF)dd%e*t1%eOh=NLPuy7ziS!%?f^cwAk&k@vKD2|LW?=qelwz zxURG{rWnK&Q;Y~k88;aY7V|4@3a0w}dZknmnJZ;{=0a~g3lG5RH-+OOKS@aWUZoPTu{Kc8iL1|6Sm8DHN*5e^*+%!#H6}|UG zNw?m7qZpf$N6$;+5NNY*){8ldEH0OA7u&932F`*6ckk}IL1~pMj9s3dPY-qiO4#@q zHhpO7$!N9qDX}O9MdiSa$K%y}nLwI0_^uo7RlA4#7DNmBCZs-j-!ZdNnsc<)AsFGj zjuH@4zuccrw57a%GNGg*+z z8Vgb)fB(Dh{lMW@_~`D=y|=VAtBY4>Kl*p^;+57wN-J#y2<0ZUjzC(Gr1e){ zo?I>D<*T!klPByqqiUe5B1H7jr<_sb{PZNE4os_cU=eLC2w7_pp`7e}@bz!~-9P$= z#unQ~N)Z4dKve(u-t9?gp@kh=uH$O4-kf~;<=Qtrdx>fjb1NB?LQy&AQY+BXbzQUZ zJ_JBWIb+OPDFx^dkj0TE#1OjCpnChmw_M28aEcW!m-BVo05TQs_PsZnRhv_9wB2kv zL{5P(ug{?i<5_hzKb`IFv~6cpk%1DX`Rbzg04xf@7~DCW9p8U2pCjK)$|&mO-L2F5I??4XbyV&bk3WnGM?!@ZqD zX@gW31|{}a=ly&YLl9KT=uOu)0-P{q2n<R`6> zTYvBSAO6w*K!!VjN{|3aKyR6D42J##AF~`sK+*&N+cvw_bp>wpwXaW;~tzPyWmQ)!jR9BO(!zA|wrx5tK0N-2ew> zFq!C0NY7U<*2{+K-FkPpGp<&f-e0d4=U34u1sV~G;q2MNCm|+b)JjK=0um%^WI_~B z+UD4|7wa_(9F;Vgj-%LBUdzBjH7PT*iywULgZbscIyES#&z_u0PKR$Ew43(mtv8IA zFF*aX9_Zn0WSm)?U+(Q4HtFEYhtCtULSZD*V7`t}4UR^Xwi4ZfZvaGb>o@sTxNE%nU+aSb{ zN~L>|Wg8DCn4|YiERAy}wE-FFV!7IA6FKedjlpL`rH!>J`WS&ok@3L;0kWVlDU31q zO&pZk*V-0_w3ZYp(X=e*%eDa-mH-(nZxt6%YCDa{AAIMVci#CZ8w;XX>)F@74a!DT z2zgs`CZJ%;GWj*!VT;OneH(1QgMzXx!3U#W__nY7Q z=x;yy%NVK6avkx%{nMWx-MPDaTOn0Omqc#k`_-l+P0X2ykPrwI>Dm4*qHX`pR!>u$ zBPs08P&ob-Hrng9|w#ksSHGSJc zQBt-NVkT+4A5?U3FtyCf)7XXHRn`riCEafNwpWjzKk3);;Q02=JBO>wYw&3@9G_l2 zFRE%(I!>~Cu-jfQUp+omTJ7xay>a*UU;pX9Cvs07Kbv2lr9LnKlQuw=9pJKCzj)DK zE;xDu_8Sn>U!PryaSuQH%oTNxv9LwLjDVr_k#b^o##pTiBc?R-mvi=#NPI7f%ycqt z+c^M_DmP!Wr@oI2h}5!FngqD%=hiqeqJ&1navfGtz$VkB`1pD;4`EgoRKX@BT~?zq zY@#o%0vIZ7i$X>2PEO~LbZPAUH{NL0=bLU_6pnKik;2w*PRzx!y;#Mn#GHVX0D#g! z2*CMw|M2e!2%r{)0t}=C7&!?fpyDRf4H|APeZI+gLk2Kg%ppRiE%_XfDC6oyxH|1G z&X(6#dS~I+FYW4us~z}&)-uG@``*XUBf z^y=~RE`TOf;zLZU>&t2~+q-=X!g;k!z3)RXiqIHMq{ri8@6PP@el@!VP6+@qfhwwr zyZ5c{?7ea8#b=*<{+EA#aQ~fyx87I8NSdtK-9J2->a#gVhSq)4RN*Tq@mQk z^_}0BfkVRJL&)f=;j^7*>-l1EG!84dcyTHiJSQ^x-EX}A^!elUS+K?p$Mx-d_u8u` z(D;Is(PmT^lhLG~r}NYEXls@JzSrk4kwf0j@_G0u2-w4&tFQU z;bc+|q%7(m|M?GZ-Me#gdewCP`f9_d8CU}yq2hUN?!On@oUY zy}owEP)LMDGH}kM!8fq-%X(V(!N&`h491#G-#CTC(QGkacI~Pvj2n-a7mEylM4Y1# zMFDLTb51?P*f6-gz1vOuA~qW=bldxc>a1BWLtpiJG%}LFFx(nV@4RtLW#MCL+x6wy zX6#gt$~x?p>vq#`+HOY~1*A}{HidSRaya(g$<=(`XV6FpN`Mp`AML+!|7(o)HLgd? zO>Jw3lCvVXkxXO@_(6ExVts=-{59h_qQB^dtVK7PP*L8d60#R0Bt#n?4UzM0pvJ<#Mv zqoNw*%geu!#~*xn^v+#7o}emWOWfJH_5SZ1 zt}o9X{PGuztF!xG|Jb-f+j4er@Xni6p*G%wOrVSOH$VDnHZi~b`@bg|uCA|?a>s|e z^JQDr;~YIAfKX1bw{sw}ZLUn{3Q~$WZ%c3iL{El33?0Vkh%mNHqBe1YSl@bY2LNKmu+n`ZRM#G{oR~x_T5rKh} zPsyj;`B*x~SrYfJ9-oe8!^nJbu?!hP6UCr!(!+<3W0ImYF=1s3;b4sc08;AyptwDm zzBoTWS*$hyeS#qJhhKX~S&f(l6#(%Kx+)1ORz^SzPzJjt9TMaW25)9_zgioE%Qy|Bfk({g16O=ACZN+?PcqWD%IEu^^bWNw_fMUF9s=3QQ@=65J#f z1l4QN6G4DD7uBTX3@HEr5CbaUEXFBLAUnl=8Zz&_|BcwL*4NjIi*rtNarWrhr(ZpN z@a*WVnsPwa0%;UIKDhtQ$^O$XfBxl9e|qnow@f`6PezA#-Z**siBS+U zR0ZS&KltHi&rjz$_$J2li}i2)_V*-3V6C;5%%pWWoQ=jiNGQOx^-VGVx~>=j_4Vni zVt;3HbgzB-Xy)AYtJ90?D>E5wgr7e@d-C8U_F0i?eHH}ktU!(lQwj)qE8$n;!Qq|V z+1_w{1z$XRDcXE=fB*K;v061Mr`+YMu$Uc=Cby2d`DQk;fkWX&UBAA*x_-wI6= zHy(&S{@ypgdi3Pv;dwQh=#ohA^5kl9ab{du8bD)mlG#A-6h;?i4vp@W@4CTY&~!0N zKX6t_Y}>2-o!yK1wN_S7$^ijBZsVk$Zde!sA zIs$+~AfPP|$8#c$Ag1xr8nKn-kjKNpgvaBNs8e{gzV1;{CI-$do3_i$t?%b;Yc8%+ z&RKw%jVV;-0ALWS0(U195hBSsWf4MPG7OOm*0+bFu_n*?qV@Bx`~JrtArY`_2OAOq z$eAo6Z?#6*0?WV<xApg7{`7t7Cn;jb5MPW$h^TO8ll(_>Hoq2XrLU!L|S z&sHy8TF+2r^b>$==KoE;wzkMHAnDr$S$W&whmPC;baZVCug z1zUxbGibssk`a+fArckQji$xU?cFy$6Tam?_P=wno-g~}V``T#9=p*DFxP_-n1Y-W zNC$WBfL}fM$&YWn|9&ysx&Ps}|J8r}N$UX>H~?e88Tt9AuL=VS!4|eQ7CC1?5?0C* zqHrkc0g4bQ7SUQW^G&81Kv4AcRb$C@rdu>^S6Pm2OIhLlxA%^ZrfJ>&?8iT~t~l5oA5>;>^6c*IH=1xE;uHH}wXcnf z{<0dDgTe5{las)-f9DoTzI=XNV6}T|@}s}_Q&g_n9oh<<#%{T6&aV=q#9)ldDNNjC ze^N#chV;Sh$;HDnjk>*FPWF!0&4MJ*PPuxz?t(XJdiVXir_Y|VE;li)J1ON<8Z zA018ygJ;+08_xk#0ud1;Ow5hsf55Glw~<{MpLi|1$zj#YgU?c!bCQkROqrY zPVuJOHRIs@xOTiZ{owr%0Wy$+8$$v!>DPnJRxD=*vu!v=$TvtgS?J5h-ScNxUwj&x zc6e}b>%-qDZoR&(|-Xag*F+ ze)t%b-klxo-#r@Ky*0Y~4wN-$z4a6U5Tf3K<`7s&BMT@4l5b8X!T^dvBN65xMk6Uj z1Zee9RqtmOMiEHKua>Lz_3FVVAi@MH#F%rI-U5E|mp}a0-~GeecMk5qSv-2sZ#=9s z;Dpx3t`{Sani^|{xv=r`Owl{zJ_{*=Jtyb}kTepu# zMO>xYxn|xXYB#n1Q8+(e)+sNVC9JdEct9CWZ0y6U<%zR{s&(saPct`-*AxqSyt#&6KXi!EwnvD03pFI8| z#?;O)=gS3>f-J0Ld3N1hTyo!+GF0F>LV!5;eb3kmGq6#Pj1mT|mDSoP?FwtPvsQe%=@?Bw*6h%>3;qA)l*Q(C8%}TQ%-K?^19?1Yi5N!V< zeEHL`Zb0Gi-o0`-2%C2K;L-fy%bc5&&p*fDug{m|pm^u|zrFY2`#3owV$n{JiPT=Z zl#oCv=7b{M>SB3zy?XZi<<)*blq*MH{`lvwPR?~b z`{1{~`|caJ%=)oUa=C=-4flirz$Zuw0@&+i8xshFQWgm~@oYNLN^S9#0?av+GRRC? zGbaGhahStpuvNWxXZHA4pAweEXn59MoS&bUqy?iyF995C;Y^Wz4uer0R_$na?0pyJ z^PilaEmw^-=I-I%Sm*4!$_^~Sa5`&O4fbnO)@L!~wu@b`rPBoHD7Ha?@_hkYAt?eR8oGLUIR}>E&^aaZ$0viT%xzGJf(C^Ru|~RcbgXr0ejv-j?Cm)yafH z40^kC6;K)igJDpJh{6J*FzKr=E`RuM7GFJZJA3u+?)>@^gDhX1zxkj1Z>zVyjt~D| zuG|^^)<1#8BMd9Edy9*)!1l#~f+&(1j(!2$7 zSQV;?$>sb!Sz@0>6OCt10g&R)Cd(Gu}6BdOkCRM#N8Vz+ewk&jERCHR16{J`VtJUhN zsH(JC^nI_1DY9^yj;HHYM5T;gGehVSC0<`$@&?XczP!3xZRX3OaJ4Q+mE3*fK&QNX zx{!@m)?kQv6a1nzrY|Ok*NZl_+E9++O8N-CX)muiZvcW;#v@1;OX7^}`u6&Sw}pUZ zg}ZMYTZM!&E=N@%quj2#NVd*hA2Vl`%9KE?C@P8sDg}?4kzr8nHZd6zQ`RCe`XC6U z)f!+>4fdQ`^f90)Wou^?Bs2~&mkxDVhrVFXA@u@q;X|+Vv{bqA+9+X=2!V66S?W^q zdO2{V3|2{6D-KwYvuL|z86s%Jz_`^nlK>J$m6rL@XQ#jT@#BB{XSwxJzD!EP&`xjN z{op_PN98RHsVd+3&g_23q-pmqD3xEsg0{#M6c$ihY`OpeZnszltN~M)a&j=;o4)fl z0Vq`cYO#2Aws`g8?DH=~;q2h>;Qo8%(H$%_=<0?{ird!Bgv@}1!Z%aP%@JL0_Hu+k zglHrsLWW|1RDmrBa*qD^Yrp+FrugC~KYsA(FR2_{HewYPm<{54w|47S=Vv9XG7m>J z3ujD38Wc!QA#7&5hX@LQ7+52U04aJ+SQ8P^l8ZQF{z*#rlu}+t#ysy z>&jAy)1Cdm-3-jmWHJ~VzEv$YW5wjac^_0-&g!ulxYRFFo6D-GC$%c5Te(3S2a8;2 z%);Kc*2!dWZ~xY0arJWF?9OJB2VXv)pU%(DUy|r9b57~o-~IYKAHM(m!4toDwd2fs z(N+fQ5h%!B6l}T|r}Juvq3w4L?_Q;slnF&Kd#$KjE@~Kn=@y&K(3T2`5=8b^+hIKz z45qj4-I?y!ZFlLfd~DjI+qcoddcM?GYeW+i`aX6Y2k(uup-)IkYpnnkK*r!V?QCxv znl5xb#K4R|9D=t*WJ+)aZdx(`0$M8&otXiNGZ-KcjYfz=RCZjC9$#G4lRb+K_rbUd zI2lbMVR^lvHR^i#!GDt>IfFckOfB;2=kSQ(j?Bx6>KMH++{>7IU>t-y2f0(wg~yP+6t^MkK1Pey}~x3`0!21QU! zovVQmSgO6F>hAr+w%uG^F3(;qUcPwwXa8nA9PPjR(e4}f&1lLh0~pp0L;x6AZssFW zkmC)k?grk7VifoWk+*{r5&>r?C%xUlB%{5rA3j92hNUWlWx*pEyH>Z5+_HuhiWR;uX_VVx3Rx?@lugo z&6mpBqw(ze`c$DRtd+Gcbkj&)Q#oc5;5XT6S$h0hW}~J0HIFyMOPuVvd_t zJ-+?n>Q^tulOfH<0BN)Kqzp(reCJMCmwon@Z5mHg%mSp!A(|sxzAVpY>z za{|h)9`Cr}WKfK%8k?6Fi{~$ZgQ_PElyMr0f!AHz%g9dEn3EJQUcQVm-dJyAL``ki zRaW)Qswzx9w5_x(Knx)SV+$fo(P!bZGD;~Cjxi}kLK=XD0INV$zoBcqag@c6%DRg! zf;uYQ_55PTNTJYDR?gLKno!=F}cB4#) zg1`P67!ZIN5M;YmB|-+Umds#0nvQSZK7RN8W`1?@t4|*Pb{2ERQuf?JSO18ZKm=$OvDMHGUA_|C6Uf#~V26s{nMpg75e*gCtfBNr>(lr~e z5h5nex+hf(s^l3sC16bjOVp?cwbC>m4TVV&Wo7_KF)6K$0VKWEfpoXJ+B7sA@A}nJ zc}|&^J;#)L#m#bYc;}XE@_0Io45&gm($axr8thEL0FexwdiAI)H4Mh%@#OgI`NJGr zqer?PH`fd6Tv1pgt;>3He6*OiJ~k){Q{P>O0C;iHTzF}6*iy=XlhQOjn*RBp{M#qL z__7|?zw^DXDG8a~;LZ*PpE!k0D=}Ki?Q-qg=6byuRJ&v)4J2+NcqPm+x0WE24fp!kMaygfiO05A~TptEr6 zN#CR}1?lx9LFlyBZZz5%9N%d!PM0TVtMeE0vorVTtNr&rtoLuDCO~tuk(1ZlYSJJH zP(TDzxLOE`^n?WerH$-croO(b*OA%2DM(c zL6Egp0FXJ&W_y51gas9F-XgCMF~(qB1;8SxH*3F~M^T8vn>Ne?zv{XrheYz$(O8d$ ze173m5H@yL*F)1@HkASDTQW5#-7nXp>9iP?g{e*-KkS-Do5|kM-pT2SQd*QH=G~+H zW;2IIkB;{??M2&hyJ^vw&E;vAbmT~iYBGi-D*{b%wE>@Q?H`gs4k1W@AXTaM-n+ki zarW|8j|KXtKYI`aw6Pjwxw#C)s-WR)3cBhS=cxxYmJnd+34QJMb)h1L-M!r$qN*z< z^W_(xrDoG~oAvq{#6Ff6;awL>;pKp6S8_6}LjzP$R|zdrrq@spo^x>&Y*AKd%q-~Y#l z-}~J(J>Ek708l`|7KjcYpb%JKyHh{_$e@0`GP_X*Z{839B69QKCwP4$Y@-1;m+y8H z##wF#eFQY1L}@)bvZKRezrOF+>vnOqc=bH4FN@Jc*Hf|;nF=(3Y?b)@n)~9}?LPWgLp(LfCNF$-Xy4s|GYl%I;CU>X44+2`l*s98wI_5z&%E2ogvTtxWtftnO zYV-1XgBK`@vMwySk?Grxv3G^C#x1W-C3{_sQ;dX?lb`HPmSLVRuCs4)lFAi^>~yp{ zIX3H6>f1P(3<_6{_h;4a`1)*-v8^Wqh1@Py;7ZD2{^Ak?AcwjkZ)5*bjWP?r$jYnzw@acnR?bQZiF3K|3@@l!JxmvBQjVxwI)|YdG$B~cF%qEkeJE@>oa`YuQj}se#vy=k zMx_CWb0$(CS^d$QyG`N;%hgFvn;gr6CQeTV1^eJLub0=O{oTQ2cKhx=Ikj2%qArWF zUR|GAPBCRA7=4raR1WL19*`iUl(OHy`<6C3hYVT}sa%R8=V)BzCPz;>sEs6JX4qIg-&zTWzo&50I=e;4BnFclYb>Os2Ez zlP6TD+0ou$QeRzPU$2&zefY&^U;f}{zx>}1`p8l(315Bz!)`wYyHy^q0Kaz-QIu$q+9T3KCGm7R`US+D2UTj@0BAV?xc zn01Ef{$YkbF+Y0o{L7bDzxe9Os_Ru|1`O=6QjPEL+}+X6RHa2=?M&CTIrgh&b9%M9 zd;9KWT3c&K7uz5^D(N2n^1+|~#e-iyUR;HDzH|FK|LMONeEs{m+!NIJA55UzP1)8N zs$OTfwvjH}eg|(7kz4xkb_p&hdHaBW4UR(GzIG5%5)j?6({C)Nud~I%H|SQ#_i~(A(h5O+<2Qb5GTjFeQksaiTQCF? zK?GDtynOwJ!d}} z41$N~Bk~&Oth!=(<%`-fWg#xa?xekO>kY-E8m?2|zF>R7wir_mWy%Nv86^pG%z?A)$Pvw)wNCn%4kx;krI@XQJ32V zFE20S%hSzV!q$*N)-dOKSOtY$*Oj(3hPKt42GLm^B^8Q}W|NDvSGR9Xec?)5A%SR< z=NB*k_NTx2n=j_qaOZ>BH~+~$9ent)6gvXuCg6Kh14;-CKyvfQ-ws9Fe9U&NQF2qM zvOVu^4gEI`i|uj^VcRn+0tAv^3zFOZ4LJi6az%}!Ht;>-zR)mqZ?;ioVIju;_s1=3IS)|-ENKOn$!i)%reBH+I^t7=m zEz^ipU5>R=DS4%>h(IPuJ(Wfqhf3$1H7P_R5}8FQ(u$awS%^Rnb_ewoTxqY)7kfi1 zMuUJdHYJ$s-T%gSzq>awoAaybbi6rB)2h07_5A$#qoSxrd*jq8fF{YX?Rqz7KW!(o38YL&qy4?%bl6_abIh+Nbu@KFw)pbu(N8azeaA$&6~2ieLn;k% z3{8xKF|AftH5;p}9*k4!guyCuwGyG+FPEFS9XRV7O@y49=Z}B+r+;~N2Gv;J`0lqy zAABt3k)Q_IQceUwZy)V)qxtZSt`8*J#Jgz1D53;WK@`BPkq#sa0!an|K}5*_jFJKL zP4)otcGpXsVB6FpS&)Dcw(TjLUf&*av%dockkPr_VS06bNj)g9KOrm_jR|&&(MZ05by-T`#Vi6&sJK5&*&snL7bwA#`wuE ze|~g)%a}6f44{ZKGv}NTjn*0w1we0FZ;CQD{d8v_go2^~MuS0FRjw{~#>2n(w|_P% z?ZDF5%wikc)#>i+_Gov6+=J>1(wnABna>_RD^P>2W6>qZ$piCRBPnew=OAZhKDhN( zRSm!VqmqJ(9)>QiA%I{+LFOMsLG ziOE@PH|y*3>#`_^qdiCw1wQ}T&wl>JS`oeb;qiOF`};IJ&bSTc(#;ta|HEJdu#GBi zFE13?BG3(sMMw@|KR%B$-QrVeYkT7uRySm>!SY>oa2Pe4mI1g4d6pF6)b^)a7-vSzI0NjNaPa1G0Vc z)!waU(+_vYR8o7l9Ah{?**y62;niZzk`o{^h)6vu2c;T1U73Od zuhyq4hLa5QjX&+es8qEn91)Qy76)aDDH9VBu!v+JBBq_vItOj=UC&CX*|45eZdjGLXuI>HaU~q4LKl-F2#M}tzm{K3TNN<4`S6y9AC5L)43V;?UXt`{zzc@Jy zj0VI2kU(N7hg2C?jiA;rsI)5_U;=`~oEl!O9-lco7>ugIC`GG|HD!GAbTBH%JF7~m z==qnwc=&2XZyn(Kf9LPi$M0-~c@_|)E$HpFW^&U(B{!)6+9D8z?bgdIK$wjn3noS; z^pIK=J@-ol$nC0MT;^;zwM2lXB#6dVBB+cOWk_2=B!$Xp5EQL(dqO4$sDT401v$eu zMlX3Q?*O58_3Ze~gSXd@{^o~;mGV24k`X8++s{=JD$O}b_Ica2&5%J*fI0PEU0hs; z1YiL-VhkwGhsK5&0ccx=VvLDQRw?%Fr$7Jk-r*f%9Fc;XRU9c}wp%y=)Tk?C6QQq6 znJBrawV~_9<+|(ar24mi^50!vTo*@sD}lx4l7;TyfBX8Y^8!6`Z&X!{cLGZeUYC=Y z`TWHhsxX@Fg{H0Q+LEpNu3h$v(=!3I6ZLAodV1A;xmn#!eli;^+xg_JdmsGvcYTol z{DfAiC>(d=va*lQU%fba8QRpg;q2lf22Mr+tIRnvYlA+flx5ZC!sdZ_6_>Z;ke_Nm=$I&G@H+knQmzxi&hjo++#CW)Mz6$%#87o*|Tl{||n z5KN4kjja+tn3_*sKFF+gOH(*yFk#FCyBm^Y-&OTUE5)AO-c*p!&t5%$_2hchc_D3C zBMfUhC{<}OvoIuGSb`WL+p^s939YkaC3ilv^!*yR0HltE;RtqA>~>z$jhUHKU4=wK3WNSz8(%LG)y#s&cY(WJ;rou`UO| zf{sK4g@ipS4S>J_KmliM%&oWIQ7WA98Elm=s6%t_cN6jB$Dz)A$0krUqO>bMxv>o2I8n3?Y*07BU#;R^qi9tyMFN5K{>M#O=;bv&eG5J50)3_R%0L4>B)R= z$N9K%Y@0SjR{%f=YzI?2aI0q3F0a41UamA=MgMQV`qjyb-J@487ORgwdKV*|Jb$4Q zU7lR6*2@?pA;kbq2#k~^>P$*2McQfrlX6Nqi;!71zV-2NJaX4qkWdC8Cc>@81bMcU@JK>HW9%A*e7ng&SR+KUwj>88@oTNoc=#wE_(WpfHkh@0@*h zF+W+YE|%UP>{nWsx^`-kqE-r(a*h^Vzw}M<;^ew-ns#j*92`zV3S`JC(xi|`D}cN; z3n$W*Gg`C(@CaNM7(!nZR#65-&VjVjngpcZtRH^$<-I#^4#w5;`s{q(7i0eVZ+~2j zYlOUQ+`?@)I&F`N>epug1O`w5xGg0Fj0{>~N02aFsQG#S=KFvu6quSI1vZb5M z_NMzjZN_iDsY{bYP?bgkDMd=97*gL#1n)N@RoivT)5r5)eLg5^Od&d)&GtsO?v9W5 zOg${?p>iWo0y%D57;f^(z^*KAzxz>0(TEr3*mqk*$d(A1IlWeAA*U=NIZ5XJ?DX05 z(+lgc1W*bDKq1xjAajJAwN=2JB!K_{Ny-^GrOucUh#(Ou#hI1fDpZO^G(!?VLFiKq z&GKXcR$q-RMtQ_ zNrKEtW|NXc`7V+*rP8L35!2=}K@13#VoHdEX;Ce@+dJhDQav7Qe0#a{05EZ65jTC` ztvGQyoZcEt2inA<fNHOQ^s-mz^7sCpJD+(e7*+(A%vl~`MD9CLyO=Mn9caCM@CyJii`F{ljEFizR-}-SP;Hu|t?-JR81#egKZTr>vFuqw;ag*J9R ztY2-;uH>CuonK$R=zG*KMwyM371Md%8AL!J;Z-Xw1B)~%8AzHyGCGGtMP;E0z-ZQ` zQ|yNmQx8X~F0b)gx)?Je@z@RxwhnM)^8k~Io2h}}%plsBd(N2@7=S+c2WMZ6%2DYc z^@}KEh=!vgLGax97)Sf&<9m0Mf*8X2YVA|rB+LSBpSmc@;ZAM(HfjsjXr-~NKmeEs z5@(Q3WoKV4Of0P*cuZB?(g^ECIw0 zCWF~dKFT0IhLpU|zS&%#Ezi$SUp`sBc>Ln=XT!l{cW-xa=T?1mub%9Z(TD^jlo%?*djIfH+38s^ zFn}@i0FbG0*5nj7K4ip*rVGB!oI($SvI#j#W?@7^MIi)Iga|AG2vL0G+-$BjBOy!& zBhoZ1>X4)2q*DUHOk@peW0lRiC;)O7y>o_RBJHy8oGSrQKy=bYS@muA)n^Ys{CMYE z-~aAtcS@)rM@YSh1~5npMBSuOB+J?7{mJ9%@R)aQNjajFVfoyD_0z@YUuy04-v4^_ z)<=2govwKg0s*vu27pNQ2my18af6s8g{`(EoB_@2Rv(1Spe+ak3qTS@q(HcE7HnAp zOsnZ^diSm455KXxzUWuW_IiH)^4ZhJkL>KL+xOlW-8-x%du6pFkVF!|)~%@_;ma>R z+k5vTGpLwz&K!czEGc=(db4W2`1}{`W7L`^S5_a6f+d=ycU+MTJq*vUFNI zL$0u?p7^$}3mpb|7fnhbq|8~o&#?=}P?tExzG35q0kcxnZmuqx3jozLo&huVCPZP_ z-BkxW^-zf!4p~ypj*+!BoDvh{oUayn*#$4T?bfcsC|MgFAfH~(o0H(2vPu`$OzVQQ zQK+Q{r^d$$hWcxSkO)3 zA052?`+xk82E&=4LAY^lC_okwK|tWlqySLqyR)jxPPxJ$X5TFrO&CwES8YmJnMzBr z8l|wVC^k(9nL&#ZuF47(S)~aIM2|o{D~6OI$DEXEKq;+FJ*X|Hl{8PDK74q-MnDoN zh8Q?st~b-+Fd;|^pg?q06-l){X;fti1UZ9Jv|M&ggy>_G7*ps%6phVBNI_9j4w4Wx z;n=C1G9b^pw$EueD63K{Ag4448?6~gYaEU0rfIsIlc=0ypE3)zeGdf2P>4Bt@Cg^2 zWhO}ig+`@eSd@ivmUJ~73@LSe$DjvQ9byUvlAdHvNJa0PE(KHy$#&~55w13CVjK*I z!FN6;hE!PHL?{5MOTCXVd27_(-tngQwcVQ1qU4kT%OsH?BXwQtv;{y`t{AG-{PO&H zF|CK*5V=YrAsIkG$~Q+$0swIbcW(X8A49lKVcmTBG@iX!ym(sg?wdOYYG+?^=G9Z| zylLlo({>lDzDp&hP!V|A+t6<%{daXJ;{LRajNc%GuuRc)C;VjEB3sv;CdH z!J(>0Xsvb=KqWbC%XEPhfEN)E0Rd7Pkx>=exa$6>p6%=$zjgNfnh(PjbAP9cERsz>QrBy!NW%>7m06$WdoXM@sJmLXeG8Nnz!9#$jJ>%J3G z0^A1~4^4<^xoKlk93^UQeaZo%h_JE@YwYwRWnmv_M~!1qqOK#3CZ2 z;RKas$f>YChGB`Ep>XB(s&R!?q(qXiGPX#L67U{a=> zBBM|SNI8j!5o*Hv`QyjKdZ=v$g)OB90kRHkfe?iR!2qH-XUu`Lw0ijX;$84+ z=98zdKBwmwdDE@e^DtjE=j+fl&AMNQaQrnLuHU%4n0uiH(pd)_dIz9iZoY!c(#WW` zv&mq%YY%SS9v$xt5BK(Nz2&B(q8c$NB#Vgv6(9qMaNgQX5eZ2+<7l*3)F% zClBBK;GLg;^0;y|84R4R6M$7N21y|q>rk?w79 zfaI*-`P%zkjLZ4v`g{>{5I`ji7)Q0P71d@W+V$=3x>>K=7=kZUxxw6Jt&xUx8ADQ5 zg_L~TD$%A8!d%pqMQQukCap_7n7T=}ee@bsNSrb+mW$z_RG`+44-k|gm9rpSZPr6K zjF>`3k%R=AXjoLDP+O|70HNs^lrpVv`-~y*s_neb>psVbp5d}h#y~-+Sae8d-s@|0 z)=Uf{Kv}!OprINRD5Je^i4<@wowa6a6ot?)`i)l9cU%Z)#Y&+yN@MIX_pOhC8|}-Y zxLkM1_v2ALDJ^s|91KSFuF}GZIU^B+qG3G*Feycnfgk`&&+L8l{gOrJ9E!qCr{kvS zQCKlV&T+l=?b=mZlZ3Dht-?qTi74lsfXiZlgpVFR)ozd>;Lfh8vcoB|2V0@q9$Nt< zLui|qpPl~g&zh&tuCJEL(t2@v{^Gw!EK+CyjV=fE&b^)cZ{9yV!m>_@E}y^rr~ixp zxexuk-NcPgNt*Q)w0^m{=+=Gin|2la#pd+EIa!$QR|osE*;{Y!zxBSGj)uFpwKb>= zk|xmG-&cTz8Ic4M5Gpp-I&*yd4&?KT{s({dSAYH&KRLSpwtcta6ny8I(bn$OvuBR1 z(YEbFv+f=~dHUCX^|xK0fA;C;ejVOD+O4%|IV$CP7Ly~3q|BuTj;u5w#?feyBpT(m zl~~*LHVA90g%LnfN`#o1b?ww>IN000o$p0~-beH)E$8#q)fq}agGfBA>+!&~?M7q* zAQ?tG>q!m~VrH?TNC14HyAU!VhNkJG9*(WUb?Rrc(i*c`#*B4}oi@hj01P?$5U>wk z8Hb!S;rVirGCt!qAadvp;NGknP}Rg_wUpXvZG>Z?wKaBHQA7mPi3N!h4c5!my4_s& zyxH`kD8#S{*sMf>n8Lqofi+m&Yk*>~EENKxRx&J2T^KNWQkKXZ92FHQUB)P@_8Q2w zT_c!NVnQYatq>8T4l00`EUVYxv`)>(x{6y_AK7FXv#__N>o{%>ey zD;5!Pg(G0F21Nm)gjM_Oi<6)H&FL3kwC7FRiLugI8SlF3Y&1H0w?4REjCbp!TW&BT z>rfd0M8TW`0>;iGq|o;v2V!X3RR~>Z7NObnoxgbcWxVRIUp;^I^6c#St5=_Vv3ImL zx_fuHw^!{RxY1a2MOs_qwh73b({}XUmhu9~XuALYH@|r`KLwz+-!#k1&?ms0BiECC zhDYZomr@QgtLKlO|IIJHe0-8z0aM}od*!s$AndetI|mz%eM+cAL_#KQHL?ii;do$3 zrR)`z2(*0{5fXwH2wN-;3kgJ>B%z4aQPm?dBP6k9LGVtuyl&R(&i7r&?WWmWE_2_s z9_rGJDmU6GnQcxnCf^0`yWmQ(ip~~mjX5V=ca0{aS+$)v*18IP3}m!IbX56>P^1(h zsNDH1h$%A*GfNk_4N{jhwzf^QZq}}JmB1n_Q#Pg1iPy8?urveE#u!}{T4^J!c1NS= z*L}ANX#$7|c-6G)#fG&2>L_vDvN1|BgCeJN=;NjbAARq|8VG$D6h$}$H(mB8+F=kFFXNKH!0_B>nMXiK0f|Rz_#()B=s45Fls6|g{ z2AG9nh>6j}zIRG&Sw%)o8e@|)k*Zl(=|aHx#E>AyCU*YC>1NaX)gS)7 z!SV5ArVs%%C`Bbwl-xHbUtN6m=+%Q)uU@UuL$y;JzVrU%jW>t4?hU539gI~uK{p`< zpexw=r8xnBf)a$Cs{zI4EIA;^DDNXdPASDMMSuUBA9w4;W`5DFR^91xaq;5$ljr8y z$zVJy_b1iPzMD=)v!lUu>L&YJ05V8s&MZKnatcUz`_7wx`1k%{8{%X-o?kqF_2PUy zIT#HGvCk>jtL3G;n4d1%zyA5>Up?eC7^0z&&)b|L{ru5i{>jPbkFQVWS7)zAJN4K9_z(8J_O0R0kuAok6xb4OdJbvZI0VcB zdK-VaNlHrIdg&nft@U5>Hoho12hJIQ`?d?d-7KzNJ$rcivmdP=U0(Z4g&WlM?C9w3 zH@<%NTi-EG8$!{(&Pd}w`!GkMiL+WWg9I_X} zN^6yKFq#M~b2epVhr`sby4d%z@4Ao@ro@UYfUqRUT7*e_VkFMa`o^$UdORtIqp{IL z=D?hc(MD5D-r7Q8D(fA_(+tk(0z=_)PG9xhjG0gQ#pK&c>S@E$IG z001u-bT}w$(n>@WV9uAi27v|9C(;nb}M2eXe-So$AOIfzN z5)qc0A&GVFy43gOWaMLuLHcfuN-5#c17-A0=L*U!q7r67WQYtJ0EiikvCQDgk*(|5 z?iesJP`lyaQ|Ci}b-lQ{Lc=NN5*3J4^*~$G_JK3|5JN};3b+{-b)nqenEK3JmrJXi zN`rDx>Z0$PRkMzS77J7vYqfUME(78M&gIg?x~U#i}ftOjs0V zcQV~63yImHu|}*x^eq)-O?5~-8*>O*qOf4w^#}}#0d*GUlu}ArA;(;SD5GOY89*d^ zjtEgJYqSDk1Vj;SY@tOfF-|j^U}H*|A!82K5MqzuP$-8G`XVb2nA@h!pi!eG(xLaE zDO^dUv?3-2XpN)^_+5>c!{W@U;&p{sVe{`rr8_2Jiuy*E~0oLoLVS+3VG7@Bf- z$If%h9m$0k`@8PxLsjw2L@rre3Kvp6lO+1$r%6gn{D&N!zn+HfPVh~iLX32Ie%)Tb#OO z%kgrxDy=S@?Id5GH4(BcY|IQ8X49f{=5(==)GBMVCL!Vwfq*k;ZJ8y5bTN=4r!i#) zR9%WBCgf}i+~ml;T6Xb#-j&u^t7qkSSmwG^S`=;nY=oSoDr>3}2~>sdQW62k-~|IG z3@kn~%DTxxWkwK4F^Wruh%yIlwjtZBkpX>Gxq-5hQ7cP|wF4jsWkAHtY^?2l%$Q@_ zBp@=HkuyZekVI)il(GPV2&$-+&MApRQmAeU*9q9GtSp7V zBdbYe!6aD#WPfkkHac<4(JO8H5cuj9D2z!6$T+3!ph6UdM@RcjbGutEmaBQ&hK%UF z_hIAb2?$L!K_wK`{+{x|TZK&so2G4j(pt@CqrT~?qI7!L=a5y4fFb8D2Bo)#Gtn9b z#*)zh%*i$}Awt&LD8rOAsFbk{apS}FvZ*UqX()}VN>yqDD3nuHp(qrxQmBm9h&lsu z&IQ@zIFy=!dmlOUUDpRrjF>xbT#=D|mjys;1uVjO(>Gl$8ib4~G`XmdSQ(Q6wmoys z6$-4NPASB`O+ZBCy$4nTOCP-eCbB6rDhCrD-xL&(GJNeDh#`kf0B(E)Hh#U?^s5*XcfQYjHD7-5@X7O+@ni*vFr7eQz%W<^5y2B(G;L)I z4vXzVOA{HRs(}$At#r&Rh#-QZ5Oq-&+8BY1vOTv1^f z7fn6cF||z_D$BZ`uj<yVS6!7S1X6wJYIJX@`h3hj)z1i36qWR6;_aeYeB zr>^a@V3VZtu>d3hjJ;OGZLn4;2q|Y^sp`TgrBDi2XoX5w#6rfZ+z&|KaCURz3|Y1+ zaO}F=vE+~wLka*&tY+Y>6sbnemkXn?a_wkX4=POvoDH$kMwB2@m6(;*!a{kQSVl<_ zve(+i5JVF&0ztMGAS+FYv(h>wW2>5*wGTN4SayI4zIu6i@bc;Yrmlyx*3MmFoziAF zRK7KCf+WO|tYc6>2+7~HTqW5S=CUvX78EL)#_>f)kp+kV}jo?o0@#}}_4dAPp|Zynp|kT@m9 zblpV|6;jNoGJDMF`YLYomCnF8`f5B&%(ko)Av1)WoGprKhNJ`l1sR2awz^l&nTS|W zDaASEye%pv{ntPHVl*Aj#?ze+3*$Axa4@S5_e7#CkuzOhcZDqk8%^X@jJ_4rYEb5F z22X?2lmh2SokXobzz~5_oH-e-Kx?fXa|G@=rHr}{UQ&uN7+d5R0U`sYxIi#PS-HC2 zEk={kDu$i5-B8v|v$>vMUWXIt1An z*G5@u)Sz-K4Ko-(r6fYMT1UwwplqQF64H(>U@8`yt+PH zU0nBT5B(a(HNNrQ@a?1FxL~b_z1P~^PK_u)Dwmt}y3L&r<&IwUECj-+U15qM=Y+z{ zK+0*YjDpdiwAu)h5GyjT+Z}-rnFWzv2c`j)Rz&!ZzU_ifIdL(tv&tUM_G=qQqtR&Z z4r1pMwaq4l-g`e9PX~3OWZies6tuH@R1}V5w1r_tMY=4tHKJ4oQUt&`Dbm}pf_07* zQ%-`|^+7lafmVfa!_Ddv5R5B1$D*h~sb<+2jRF|@%%n6ih?Mmp`E-4?*fdS**O<{c z*ENeAhzXUki`A-6Ov>h*7(_rR5+dZL_rw{YS%qbv34}0YwbOb|LSK(JBN#8dNDqBF%}7xhWM4J|s~ohdxRaj6QIt z%Pz7&M2HLuAk%Aw9Yq^*76(=%a$S_u!q%3uq(L>>2EJJs#b&=?lq3wS00b3QW!d#z zOrW$*IVn=BEay~*xue|I<zq-i%S_Hw3V1KCJzJ2TNt?5`nY+J#WL>r~7$)q)l$}#mZ34)+% zdJm+78_c`h^?{HGm1t66tgBF&kALGgzxP|eZ>*IpNT`$*$v0)ZxNX$lRy-0SBB9DywRLTcJ5+#?~O)*374 z_78Ufb6GjmHukM#jskwOaz>LPAaqrUqBFBnT4@-JC&_!`EMV#CVQ4$6(NzNgEK69e zR-A#5A@+4?i{l-k-PCtJ#m%N4&IWPQ``~ko#i;0WA~G>cH5?(555DtB45s8WY6XDE zs?ZJqA!T$NeBvCnRAeH8WDnYfoJkMd%xSHCpSx~_D!~iJT=-L?sNlc)W0#~pv$R;9YtSc8oSo`crI7?vY*3w%bM2ymAxo!e!C^zd< zO$Je;j9ljoxvJI*oDL~OGC()>f6gg}RAknWrSF4M%o+<@-rq~L*=(}nm@cmTa`^(D zzSy0(I+w+7Si773eltHC`bmfkizW}#Q79ZB*hjvXNDZw zm_<0`*le23|G%j}X|^oe*2JJu%{kZF#W`L?#Elzy-_2JgX%d-Ik}?bddX@+blNumQ zW|B$J;79P+ph1HM4S^XA8Ad08OfuiQb$EpPDR!~ensbhV#$3mrqTvzYete&^_nO5R z-}nlI6uPx;wJ+VEH)>j2?XfPm^~=-i`h1N)etP-&C9VrH!EuW3zbog$|KJy=)1(O+ zO*7i@^74l{JrIf7m^pPIo)V{YG_%Kf0x5WWZ(r`)_Ql;?ARA&1VSqG!{KYR*N*I7l zh&Ti{gb2hVJ=4rmN<_SGg8#$+`k!@MIQ+h?-up$Db=v~7xqW#2FdgTFc6c~P-4bkv zbd>BQ{_f%9!^14dZM(N{bUz+vNu_FY2S%Na(|OKwKDK@bBw|U4%}jD;77PuNRFVJ@ z3lfJJNtU^2ZMrox!%z|lq`E1DrxXINT~j*9oC46zz4kD3@LntCT<`aGxnD0A3kdR7 zYmls4r@*SVY_$iecJfxHBve#;YkjM*ct55`#0oqEP|i7V?zTiTLjx{Y>vioL__YhNasK|h_a7e~Km6jmGGzMOO#lE<=Sf6CROM;He(OT8zzSP=p*Y?Mkm#3%r@(gPSDUcXW4Bvd@ zZ_dYu!{PCeaxyN{cRzfK#xI}$gs~wIjG%z%f|)Q#rU*!>pybF8|N8UuPq%v>BsZoh zoum|&=}=6m515r{Oz004e-vq@ zByzvr44tJxLt-X?)A=Na{Nejw)Yg`IuUoxbUXGmC*PFn0oRB~Qjy;aU>MWI94&h%e zwPMo-U{gwoMHn+%&XeJFwFs}}FirC$rD&_y+vUFK^Xm&CD2i*8oYVsxAlx(}0*Je* zbqwn$3!0}d+7>BAs7~|n}#wm->IvV8u$K7U>h>C<%hHy^$^ zfAjsvcc(9hxiHaudcY)kI%Y`j8_#81HgjjnYrBW0fG@7t`l>C|Dqy?ct9Neo)=gXM zxAk_r-R_tEf$j=*OJyR2 zwr#iNnngflPUl=^KgN207A%gy$cX6C)XQPYWzGoX9&aXm96=GAQyZPVC5Ku#04b-A_e+YjHZYri)$WkzVLdYJlh`%Rq>=`iEJ{p05dCaWB%fuj^WUrE6s-@6eL-s|GVRd%v>MkS+U zC*vxzWfiVbMv{98+5GPB{{4B}zdrBJd7ale@7L4x%U)7Npcl?5KZB^z9cg(Ya}A+Q z-ufzJ9z;ZZ4Q!ZeM~aCd9lNutYlCS*p8Ct@e?JeNY)?v$-4F-h%ASZm+vhqwu+S;> zk!n${+-q6N3B$}cFJ6bf{&cW*{O_-;Wt8PilT~X{xJ1^+ymjuthkcd@&9e2Kyiar# z;=(35)ND1-4Da$r!n9t3(;(j8A4wYR`Gzca=Nj}kO9+Vsn1sj%u*lvI0=?%$1bRjN zphv;?ZJ4|9?5S|E9Q0CP8bF(xATQEAzL*fUVWlJ`{eIc`zL3{#o0d^sk^f#ZK=cC( z%|T>O3bIIvrcF*wdtYYb+3{(cjn6f2Ut7vx;_u%zxvnThzQNt}F_yHA{zzq>$`3>A z3Xa>h74qud`Np2)g1Wh@HZ8Rw-SgX5Q+#sPJ}!98S~*Mmro9Y}EG0)n`T3A+d30;a zZy&YH`dLbuu-N~uz2)CB^jFzXlhthx^IV>vm`7d6Tb9`9xgim0#F`Dd!N~ZSb+r_< z(oXs#%1t?S?tL@KrIx#sz2mT$0?xCIbv!|6eY~$&Du&J9B zMI({lGpG4FBS7(whpkR?stsq@S@~JCy$cc=DkeRyH);buPsxaWXpw#XM-;8br(1=& zUZ-c-6tRxsV~+h?Mlw1G&NXpLz~W`WAZJ1)fp8i(V`fnm(c}9kcP>#&?kGFeFk0)w?rr-Kp5q=x^a-KDiQJNz_ z=HGZjVn2)J=rE%IKvhQkZDD%iuKN*~ivYFRobkxBLT(I=BW z5llYe1D}W|;W1IsCWL0YS#O$I+POgM_7)7X+%@=e?r3C4C)|je1r#@WtHyG7N&XECe>z!V#QZ-e# zo@?ZLl%or6z&wwu08B;#4B$pmr{K}bF7Msuk0Sx=`czhjEQ74;*vpF}% zZXPyg{M+E@>#KTcYi(b9hvqZdDFTkv~$UX zSU=y^|+y1^xN$AbJD z*+cvOUyko@9c$a)7SlRtWu9)>cr5NMSPCTM*O)27Axh5)d+Q(yqv|=2u65gL2bIy? zn05y(0N-Kut!JZB*zRkY+4x^5@$R1#BXU>lzRCAAmBFdOF(a z{U&ER$~hh001q*ZgsmoOfxXcWxl&Tjl=o0jfX)7XqRz%4`DEoRGHP2(K{rh%M;|G^ zSwdNS*^`Ue;}?NutE17$9sJ<{TGQbBp&DA$>JN4pkDTC~=2! zAPzS7(qfJRJ5&x2?gAW_+dU^w_i_xmJ~5R>q?pgU#p1g?N9CUfs<>GUCsot)^N%K- z_-De*AqPyr+*7y0-qv*0ea*CPJHX zUl+Ly1|wx6pG=P+7T&9uW@$(ynhk^->V6G;v^683XVCkY)mOrVuk?Q7%OGnXSpc<+ z)s}77+5Y5M%+UmUgwgg>>)NXktyE3(+cRD@?{3`GZ;XrBi4-**&HF^qHL01HD}OTI zoNq-(D^p%^Z^RpH%KFq(8|}uhQTOq>fPcoHiF94Cei5x2vO26-@WiGHoPx!0t(1L6 z)ZT*o%K_$Rsz{v?kkVu24Ny-q6qbNgjs&w+&v*_#?gmXj7tBqn%A6~@Rpm4g(!6a% zdnO%fsV#yK~pi5?!RBAtZ=jp7y>OFK#LhpV{pkFd|b55YT~`!S<3pI^f`rh zi&++DM#}3b>QBWs(l$cDFfgHPRT@etZ$5EGaQ=2X8F9TpugukLnp#jTM)aBNqwb%T4^GCbri~Y^C zJC_&L)}1~#OZ18r{kK1U_)xfloyzvE86sNpylsnVGw&TQkox|?0hd+`h;JpPJ=$g6C$1{9&hqKBhJTLTxtdXMtomE#Zbg88YL#F-N$<6bn`kd;G zt*y0c!!GN(?O+e?f8sDQv*_0vTM2&B(0O#{4X=e+H@C5^TO0BE*+XZT=$z`nE?Z2? zRlLv`VB5dVp7i#8Hl*7+PZ&+|#8M@Jl@#0`iN8DetnXQ6n*zzn_c=5%2<>o9HgVGx z8W8euGHzKcV}}k*28Kq5Z4$vSNTl?Q3I-@(ZX`|_{8l@lJiH$31{5;BUk#$CHocxj ztt6=_n*c#jaYYAVZ|TqeZf@_OZmk2lH&M$Y{Ts9V4PMSb39L^b3dY5;N>j|(I%hr| zjvoC0UCSpfVl*#!{GSS&z2kXW=Q*3ug36@7Jtb2aha?8+d0fxSLjcAzq)CMq)y6b5 ztXcp_3YJkDdDang9Ah4Y@C#7=_YxCvof(nGWdh*RXa*x$LR3lZtmEy|^9O%7(_-2` zMqlg>O;S#)&BqT^3;9$^_CAI@ucl|-bD7D4dPfwWW%tn|dZUk5R_6Jma}|<;9nX&l zB}JnONv&EBp6Mt4gjy!##Jx(Sf7sBpSa*$eK%sFJi~8j8L)>)G<{ey%Jl*pQSq5|o zc<|q3p{t2kCTlpg-o1`hb$#gdNJbREZPeLBLhLbFOdY|)H}AI9+4$snE1l zAl68=l^c>#0Rg!r;4_DgbD=4B1;~6Pj+Ie_+jF63$fR5RhJ|=ZY7|)8y+-ztCv5EQ znO|(B7a$WtSK;rH>htk@@AA)`%lf65v+S1;u2K*V4|hl=l=$X)f#0ST7J$_dZtBSO z233E0t{-Kzj<1lDOi9DxXzXdL{Y(87-)u@-Lu9#JzK^l$AWGEdPykOy)k`s9?YHk- zMutX{T9gzlJ7%|=F^7RFOC`}56x~TX=E>P!K-Xf-a9*`;YL?H*aoMVWshOJ-#@qGi zY}fC4zplKbej(?RK!estwsKkEMsbr)BBn*$>weM3WTY}GH!p7vui?Zx8{HuucD;IY znJ5p{GNf20F8R48xwEHEWu4~2l0g9vzv%p8b|^wg9}pZV;S-aR)3uEi-fjO9TGo73 z7CLi=niKvrUZ~4q@2?C?gJ&P>YJU0+R@^SCLiY2kEFYUuE!;ZDwQUcQk^1)7gaR2w9b$lckFv{#(qs+2-<1X~5rd-o_22T>Mf;F|v@-flPbe z@~*8(Z7h+8HZsy@_SddJC5iL7)0 z+U>9JESG^!DSo2hM$74L*4LQ;#FJ51=66WdOiR&+Zpu$q0diZUtFoFP%GHZt>ON)? zRMjaJqScwX@pDs#cS#ejo=dH+IY>%S1*l~KWQHMc3#6DVeV54>(=k62l*}ig8RkkW zM@oddIwR8~z(x0pft6HH?-zZ#SPS&O5r_QsYgH3-eHdUoc0?$!NHiFsMa=8&!FU8(l z+=x8zE%&8jlnG!@(OF>!f|Y-t`68SW#BD$$Z_=sZd&M%%0lug=giX99+|X1H4_QM= z0#MS|pwPd4$@;xETVItx4b*5I^x21BU7g`H4!MA+;!)r^{CMefX|Cfj*!E*DxbkH?yD5>rS01tr}XIH}$LYz&fV$K2MJ_ z&h}KrF2SKUaW65kKP`sB#PIg)+}zvBsU9ndIr-^Rta5vr5)(hSQGJJJaAoaavN2x? z>dJCPc_cD@<73!XzrV71+MfB>#r>6C#jb=Q6_bSN2JM)_V4{79)c{%XkQ$C#040#LEkRV%^yNW%{%C zZ(7D?n}}T?9&Y9@#eFbWwauJRb*9-B5AQJYQ!0??{ZG&m!Rvfzh1 zf+9qHYSlwq+tiq9xge@wHwe2Y43Y;Rup-pnaN}``?6F`S&OFWuylT8CwrD(#J|aj% zC&`=}p)H-;U}VA4r@o4fH%g9eea|e)7^jMVqZ)NEIWi17iTn?Jh#lf zz5HxnYiGSGyu!;8piAFoL!PaBH7iu8@waytkHa~;Os1D++E2!OFG&zu20H6Vi zRmDNsKQn4--4a>VMY~)7Ct1}emXyx#k5Dt9ampPn|Ul8HZ8?i?FlK8-mnIg8K$-r)iOkW_#QIW-is$cnKlRG?fnJ-&b000jg9 znM9HSaQ1-506ID_^a&WC-e>YI@3~Zgn3@zB$cH2u;5~0Qkh8`6R*KP|C3ns#_fLP1 zUA#H0IvLBEKM3x$E3uD0Bl?hA*8F4Ii6y??IYUpMEs|$%)?1rJPk7U?{+PAnm#wuf zFgQA1lgd#L%B@h2l>cX?VE8OOl}IRIUHYUPD8Z~04HIg&>nF- zfXD1AWQ&8ej>&kbH`p!MpB$SstUFx4sZg4N zOAak0+gojPUjdsU6E_%s>i*Vcj~Iy)sw?wkj<*+gF) zlk3LnbM7{IdjxyW``4tKy!&_$O{OFs~l#qd7m*c#eT@*hzA!~;j|W%Kh~HbUIXGD|YIO|DolTT! zf}@JWeJy2`4{V6W+Ev33J~nlPs^x`ucuX=+WzW{_M|zih zJPWl}oVu%%r0U(y^^B$(EnY=R?F>Sz>S_G6>d4ENE)aOmJ^*dFVZ9aNbbP#d(42R@ zVz}y-e{Eg^T(FJ0mBv9|7d$acO+^LENSC61f$Z7QLD19Fr&3koePQACybHFSnj3vp zwCjDi0gfVs8IVQ*n*@lX5q*miSo2_YK<*ccN&lNs)d^)aNUEF(vOJkFrEZM0nj&{< zC^#|Q1sGIj`Fy-w>7tav!!&YN8Pt})PoHE!0Lc}~cM4QA)Sm-buI+?gIcFAT1|x$* zDpqLOfbOJWeY`3aV8viKBKI8~Rl~rMPsm-dyf&2jj?QBSmJku+ZQcxJW#tF*y;>LY z0>Jr|BVXm)7k}wawqnl6Z>)*gLkG>u=lhcf2gfZjhxHOIIrDR6QEGSWZ;s{64xQM< zyxEHQf{*_2C@r8kwSQLd?)xys$~BdHnz{J5zHvy?j76u$0UnHzwO7-+jsM%9yVPYK z_Ic~7mNo5*c!*JVO--8^=z%?(x~|YF76WAFAuR#*s?md5V!=(le@M|V10LPjMDN709l0-cCHUft$Bk)+kEK2~qTl=>a2$E(E)ciM< zcN<$Yun=;<)Lz3T42M*KIV0lZ;)ugwVA3!n0L2XSG1nP1^J-s1Cu1Y-ojAnX&b180#x|iym zlC;k0x-US!QOHtMcFeeCFGU6ZZ*AMsCy@Rvuiy-@GxJm=P2U+fI}3w`KQRP zrK(r5QJvSHv~rDnV?>NmZY4eS1+~v@2Ie!f0F%L_1cO`t0}cy6aA3l+JNjEeqICoQ zD5eD-_p6ho;hB7Yv;y8kQ(c`39ijndyruD@vtbtt)etAVg2V%~7Ol~6CB!H0)F(K! zE^?S1V3G-w&<6reN3N>EZ~!cdpYKWkZX`1$yI`n`0Z-90B_+jnT^}N&PYBzaA3sEf zTjm6JG#^Yh{VuF_eX(?YR6Ut|hhhQU;myeT87RuS(sJyWzb@W4L%2O$>RqtY)9yhA z^X@FpJEdcCwgPkg5eEJEsc>%5Z&nAv=L(gN-iq-*)XgK>LWiejYpq{P73sjT(hH&D zJY^oXY=YguhR@iw_JZqvI_<2P?HyuJ7TTL^HL_dtzJdiC^w@=0!(Hw}C#_{CH+^R3 z-!+|X)5J-_fME5A``GQUgR@6`h=A*KjVfip-H!ejUOqA-ZSNN~yj2WI69fV$o~^QO zKFC9#@an7f^?x(sLUknQI&A?aN^9~um{Se+cIi2KUe6g^)>8(Ew{Ab&QF3`5DhJm z7U1NUhJ~lDV5PF{a2*N)0$fhGnj_S6Sfw#QASK*3;vp~%j^KO$^*lEwJ{>@Clow}3 zB%wMu3v z({)Kl(KGc{_U06Mn6puWX<1tv8Y@vbCk}1!*V?@ppgxN84TkI^tHZD3AT(+ocU?q{=zyBO>3kSvXbYfcEXi2A+-IXMd^9+!!G z-0^0}i4PU|WSy|0Y;L>M8DrDTwB2DRHyz~FT({MXX^Cht09XLmjjK$1l0A{7kZAj@ zrWz}{IA?{`ETOUc=H!~ym(~Kfb+kK-9w_@BQyU!d0-$!k1&acs)KRnavC!CfV18yn z=!#Ma2tT~YpzUA-rW3DX1$)Ku;&Bd);KOG#lDSE@ZQ#8N^d767+f2RSU%_B7 z_YEnC0G+%8HUI=??l+~;{sFb+QH4R0S6@^x0vMKztK}H%KnQqhpOY%ixLz{tJ1C_@ zPe3p(0woRjihT`7By?#S>Oyu2iG+TZrQ{B;n!~l=u#2=o;7P>VZ>v24dms zfHGjKchg%J5_|fyRRS*kox82Yeeyw7k7cHQF7isZ89uLD{q!~MT$x>$PFz;CzkGT} zSas>*fyFFZ%W|FY-BZ?<=dXX~(~6J5DcrtFC8_)dbYIxekLGI+7Of0j=3ZaFVf_d* zq4YrH%ep>%-R*|K#&%iH&ni!1ct7&Bim}`-PMovqun{G=@A|e5KTo9Y& z@^6lsbE^9)wi^P8=LN5jvccsuWrI%5;M|3w5r~Ut&Yl3wh6?M=B#)+rS0i zQFOA0;J&4cm<#ghbsW|gKm~B}rKBJkkDLCfSC{$CQ4Rzi-!<>xCdHB4H%rpt5$$L^raS0zxF4h>7vm`q*Ck zY&O`|G=^X4!I_e4tfrsLu9?h|`0AKq3(Bm?q{Fpv>qo|$w-vG059){i`bPT7Y(>2a z8hk7k^>Ojz!Y$fDlf~b^fpC9Y?^;=EsJ!&w`)CwgnkFvq6vIIC3!V&-H1rkC5~AKM ztk%fblyPp=uN=Uw+@K=NdQY7G#vk&H#kOD`2ve<~ml0ynKKqNqi!U)}6u6H{p`i{a z-36|8x~YrTk%3Jl!vs~6*svb9n(uvTU&lzv~IAkJF&MO$C-K7coMJr9Bz1S+9`eA zwJT`GL=j*U0Z19?V3c)P{ZnA!Y&7+_6fdboQ_{YfM*Q<^$U*ZPJUiO4ng1FW1P(5U zMWqvD2xSmK8XX*T#I}7WRjT*t zV+_#L!d%7H!>i2fw;ZZ=prTuDYRSo82m*N6A&}sBG0&>`@pwhCIA@bQQ|5O zQwLBrLQ(`|((>X9p5eJe0j#X)bZC$Okk-#{s8@31`243c$a}u)MW-z#tAA*V9DV9T zNpHAVtG;8CeU&u(??lLU(r+;7C^FaR$hWrAC8P8w@{Nazd?+PPV3-||F0;__U3AoJ zB;|K|yHqKw+bBKltjS;X)a~`2AmXErIuErfWnO%WUXL*oOMk^-OKJMZ`QNWS`yT)5 zE?juqLe5@m_dc-eJbY(49X%7iMDj9qwkYR`)P5mljOvx8`fgQH?LsslkM;kYis)Ku z+1k3zCtS=tGy|%fE@1usHR1cWGLUo=3D~-?3YxqjX|~;}z$W;~rs1`#1i0AWAW!~V zEYM7cn))86DN35(H1*ZEU%oOU&$KEm!$~ym3#)-cBot6Pz?rSaUbZbzivhY9LTI71lDPS!MdxD3N}me` zVlaU1?gK14f;hV&T?Uf_#0(>xK!U6v!cP^&LqiKd!&qYr1bth(f}j8#=)wA4-a;}-vmlST+RQnmaUpPNg6Kg$dZ#TT~mFc|sfV{$g;!hLXH zh=I5XbD^w^yzccc?IZoiE4FH1UXM2)__xWG%>NCKYO^EV|G}s>XS&rHAN<-hZ<+&* zO6@(`@ePm6ZQ;wSAMq?sbyYl%544({-!`b9RRYWH7OrLOwZ9Q>kfqZ?X#xY(rOUu% z#5>GqMkaHU@8Ki)Aahsv!T8LRo13*`B;38LZvfkSr|c1tZ?e;PR;0=aPS0y-os2;1Cxw?o$?qGR`?x& zg%7hc1OLtFz@X}XSfdcAJ-P1}cJ^%wZ{e}QnrO8DeK)^&#~>NKk++W*nEow+(LD8J z5|oem1?lNdr|MtFNP5C0cPvjwv-P%L*TThqblRRE1UHzes5w9M+6*@AO117cNbP0FLy`q9B>q+N&hm_kxSo-`|( zoJ?6xuvBM#qM!LGw(R~gtK)F*FoyVojy>qtJnh8D2k-w{li;d_V`+s)KjoGNZ2+b< zLDqGP1r-&x1l^XW%_9vj+gHVhSvI6yK@Q72ZhQ{Et!62HC}zmpZ*SgTZu@Zl$1(2K z^l9~MkZd7ub>`R8G#0nnmq4IQ>(0k6CrU1_Vik7Gm;sR3 zVLW)a!qdk~5yF`P9KMaGK_KCHr{u>1$-3Q8z-`4ih~!rT9vZCi8N{!Y3ib0P5t@`F z1V`moLd|Mg)lmX z>L<$Ob?#%pBnQ5zD^xCW+{(;o|1@7`zQFtZk2&C_rkQNzYb?iS@|Qb9T^A*1_oy10 zo3{2Q$HpjvWHY3N($STa%*^{g*cUj>lB^V8MKG@dJ|`(iLWOmiRrN@H*iKqiz{>*$ z7mQkLT~*aEJ*rw^&Bn7c@Zrj@p&KUI*=Zu9S=8XtwkG^Sd!-XpVACClOVwY_EzjMr ztHbJ6}#Y>GcymC6b9g_=IgqH+HuNQJXfz4Fv8w5#J+U#|i+_dW;lum7!+{&QFgx1A&m-R*x>XHlg)*w=gOX@w~Yv-QuvzD90WLRa+o`241& z1M_Qh7Spz+KL!Ksd0s6euNB}lBMRK^gEk$AcijMIM!|#*?_5@4R)Ik@g$@>>%nnW= z+D8{{IQRX+PCRlbRkT9_==ErBl&*alqBPxNZJZ7 z90$bPrZB?z)*bMDIB0qWoQfJ)?!edcR&pW2gY5LUkrMyDEc)vzkO;sEIEbb~0AaJ$ zy>`o8vcwh2$)kwHmM7p()?O+S>39d`K9}`B%c{UsQ9zX*sT=3~XJ-d9x)z%258tng znYOa6^O~)$=8rkq4H>hKrug`48-{i@60;%diDJ?n&INjTsoE~=GWx5jP(Jn*hu>TU zR+>6k0rlkXx8UJ{?QDV1#l2l5aanKGPAT&<%hS+#uyB#CPEf(C z>0d;^hmu8W6Fcqvl`O2p=o!``;lADS`b$TFg}onI7R@7=@Z&dp7fB(AawNkr<0_BB zJrjR1z%S-|^MVhj>%3F=KgtPu9nSx*5feqI?sU>65;?Ko$LN&roW1689jq>_#mIdK zzc2E7*w^X1nb1`c^Swk3u_SWA;%oOkBRO1KR_T;7!luJdk8iLCMhho*9Y6TH3Prom z1QdraHC=BM>F&lc_9&cNw4_VGq2uKkDqYSb66y72(APs>SwMQIk9Kc_m3E*CJ zu#W47Y<3){rSKj>NzZMDJiooxcG&!8Hep&YG!>;d>?dCc;YDRPd(K+;pv^M#l;X5i z3%(}ykq!E}Z2y+2+}U7UDXf+o5O|S)W%2)wIlSZU1fWjQ*(7`F^`;c6Pk-Ktqd1}0D|6SSV2-=dbYh1 z$yGKZ$RQ=?y%Yvg7NbY8eVI*cpTL zNS#n=KwfV%F=u{zC2*9EHS->~AVvahorzNx5M95G(u>Ni5X7F2GnFTP^6$D^UiyXj zSsqNKb0TvUKsQ{uysPXz6lGhL=xQGC+7_HU_22tz&LDl`|3EHZ{Z%lL+eM!JZlR-- zo4#)9o6x+}YBtr{CMkiZ5D@@J+()8($&EN&e}#sfm3=-BEhqvPP|(TqH5Q-noqFEv$$>zzg-^s#6!4?PrVw(I?o4u-}f9Xo(_s*rHd>CW{h zSQzaqW(p6xR=~+=7c3och2zSYxQ;q77G38!3UipS98huutPCtvmWdtgQ2cZ$UPG3p zul2*t7ipK@DN951li?9jVJH4Eoi-(1t;C`1kFo2bOLcwbh%`9+;FWB%|plG!M z%@JoUh7MHMM1`l&0X|KU##*vQTTG1)ty;WoeVQcstbA0`hpVex$PHzxXrSp z4T3uLf_-uDuPAjy*-AYX%3qpJPJodzMVlB&`mX#dMVPWbQc?H*+QlD&GYGEy0J(6x zQ0Vdew+@Z?FPQ}Ivr5Tl2`i7FI?C4(a7O^W7xqZ&VT#%mGad2@zd2XJ9ZcX zbC??ZsI#s|k7mL>Ynald0@5Vr2=Q7xu6hOsx&8Gi~3&LZbq8qf*u+OBnh~5}?Uv?muHcsrNd%!&ft)d&<|)%7sgh zYw~XQp0?L+?7gs3vQA=VXqtJzF+bNllhd>^JfkKN6qG|)!Qu3lXJ+qJ=OIvUTbqAw zMk>4E^|F9~2_ViLQj!E2W{0}}dVpB4MYbIpOD(^o!yF#?T>g`bx$rs@{^;zK)*Y4n zhfy$gS{n`jC??V0Sk=<}JzV6+gjcF2WW|TF@1?Vxs;}%0CA}{>?^A^^1NjmF=>5+x z;D-qV9eB35bnL)LI)I80+3+Ug^PAX&1g0~u`V{*X9tubukmQ}!ga0UxUqjv4qR#%;Zr-a zeXy||eZIdY5_ulq#8H%Q0UmN~o?&84d4CnbN=0W8Ah*}O*vxcQO!-G(p{=dIaQTeI zw1Fs-a&K>uGAU@t)DgaTg&UYjP|H&PL~K}nvsmrV=)2`o3bEe(@vBPq4ExA!uE1&3 zRHWPq*q1jk-0T~;=XM2=5dSGbtt#C_-3gr14Tk7KenZ8eQrRB23T6&Qfwj%0FA`hL zugqop_*|Vi-8itga}+YyMz`o4)mDcUXVX@dcsK1mI=Q=2Q276egWww&^-Tn9EF$Z) z^W%wJ!EmUHf$)k@4}g?zr#3Y71L@onqnv`F(2okF;%D5XXa36%_KX?ZtK zo#b%%9NyxzAK1o2Mc$4LM(UwLnm-+yY;EU^CZD6aC)v#TM&|gC0Ugnj&Im0T0W_2 zZ_91#3{WZgcZ)U{Q7xs$1CcmIBS3Ed6N9KWruWM@{AzNQfty9fsZ3~;yDZt zafW>1!at~2#i@bl-!NQrQsQAQgPXubA^EgJ$7hg@kq@^&ijU2RgxEE8N}PnBrqCh; zLSKsQ;tDyPOADQU-0dUqj>o~NdZ0<1Q7%+0RglzULj;xivv!-}u1I0s{+}RuSPrAo z1q|?Og`n#tvPJ%Y@aHd8PSKVS_c8Xwq2s@^L9r?fxd1er&RNebC67>)+e@&8W>DQu zrg!Xfl1~|O6RBj4S7Ia}7N6Y#IEd<`i+-Lk==c-E5{gJi>jCiB`Kef~pSa*6%NWu}gBx1A(kh zORIZ>l2?&1 z4NdjKmu|mdk4VcTRrmEd`r|(<0I?a$=C&6INl*y zPf)ckXEw*WXd|;qdHm$|e={K;67!Y@p0oD=IKVGnR1)0<(?x@Gf2BN>Ozn}Qeci$4 zpo)V25tRN`iHgt!;#1+yx@w?uM!*0esn0fX=q=e~i+71@-T@z)o{pd3bq9|_lC=1* zEJwUp#>W`SF`%((06%pHEhC>ysa|->QL9d(1;Pe@m0A$yyP*bLHVR_?<``-5llCdL zB}KQd!b);sM9l=`aR_{4DT)B@DCZP@byVz5w3pi|n+GDZ1fZa?A5Ps_+=AD3)K+35j{lrUt|CkiU$&xPW1kDlRg9g zxrIxdhDCc-l>nRLVU$w`Y2j7zWeKrG?l+*!K(u}=pj%9>^%aFna8Zw8S2BGbHt-in zuxMWyRMDfS#vTt#>GnONE~^V=<`?Z(jF zq{xS*`udXD_Fn(`!-wl)8Wmy->a5bHWZt9&$0%FZVyGlz5lpSQNxC|^Ua-q1Gadi$ zmg%Nl-ndzwP`Rnww)pq3p#CausiTKR^K4eXH~{LwzZJ1Lz+NUMlMtt>5wQ6ObM{Lfx~ppF+zX z8&4NYD$-f3E5q+}M_nQH$s%#8%L2byrc>Eys>;M8np2d?UNAl zpL0gmgb3Jj_rno~z~85{NAPPY39b&BSmna&aIOBY1j--U7*mLSsD;n9Qs@Ri{I~X} zfw_HefWY0IRC+gK^F#+>Kzfhs$@N1u{!c$)chWZcG7-T>7I>`z7zob}KxwT1Su`CK zyO;R$%g7?l*^m2OGj?0;M7ujT53kkFQ_8`kwuRYKfn9w)d~yw4Xw8#O;_D8NrQAH& zq)cLPMi`caSzgz5AX*tHELaX6oD4n?&CjE$I?f7^*m?(7CClCu0%-6Wc`jw@ucugg z&dVEyDJJH1y0yHD|rX9a7 z9T>JE_=!F&WRJ__rzG~)mV6eI2HQ_ymMCqLS^ux=KWf$Eu`Ny*{_TkZ*v(4;(nH4`{ahyh|_lpcAf%D<@b8)VAo?{AS_qQ#p zdO-;{JT-iW^fMuEn-`&?SCf%pWR!T%f*Jc25n?nUh(CPdezOv| zU<>Bu5lH|3MzEpF(yNUdaa!;#nf8UL2`=R`m81SA+FD}BlL@SN|CbLT)KAb*`y1T6 zA*}tPa_(=c{jMd)fdJYzeMV*<9RbbthT0Co`@Tw&^nLW#t(!qJOD5!e! zv#6G2!rd(5@@S$X4F|Z#qGZ6(e!chV4@{RKV8kfhL4O}^NhmRvK z-0N&3Y;(5%y(8NBM=WA~+eh2`luTC_!nSH_9>%rThN(QN-DA!X&>K{33i$!oUoXNd z3yd@NVZV3Cl7qIy*3z?UU&>ci0Pwooq)Xbqd= zeb@bV8{&)R{8Sb?U9qvMIvpWB2eVqx)i2djWiO~vH2CF+>pW5(St(=f#enf_)~Bgci2&BO6qGYUcUqXA&-`+ zMVtXl#SkZl2IF;!Nx|0?dCXiY!1LPI7;%j8RW2_w`GP+fyr2N0v<+UM=KJlPzc8EN z$bAfWu*Pyv7d2Xy7GS!hc2;Edw&no%IX%|*!!mb;bb14jhFY==4Tz(LqD3+tI~*~? zGO$Lxq!or|mdS~cQ-l>ANN-A$q}9 zSuu|;`<`_f?!5N+{~+Q~jrUkA*298j%G;Y2iwqw1m<+d*`L4{!0?Jy7_t?AZ7~%<3 zeZ!&3o*@!Eq)tpNW(4TfiK(d=#VhmQ=q{rA>ivrGNo)_D@J?x8;^F@Snhs_0A3l~; zhC+)l590;^-(m5uZa*;o-w8)*4h(wSXlun)%VA1+iWrL0VJ$R(Z3p5v=8x|c#Mk2v zZGUkXB6l12XaoX{2R{sPrjK!mYNE(zQLfS9ybBnBEa5i;*k=2yM{h`)y6s6l|h z5D~->{5G|C`@9*$BglvG#dxzM9IlSc^ybV#04TfiKLC)C+#HB`C;1J&AqHRyH)28* z5Ql)?`>4={5(zLy_~#Im65&Y53O}6BA9~k^zC!5ze$ik5qjhUrUFzkf-7fX|DVA$r z7lV?>DK^v4a005g$_&iOdMr^>$s|*-kZwePFaz*Xw~0!%HB2x4H6_YvqMR}p2O@M; zwQvzvcML^zL~{obfj~xfY#>Pp!Bx_+D0GjlX~CAtM9gLlB*&okni8jyWb0Z4&*#I3 z_m6o>7(-T$?k+-u@fATd!la-BV1yA+fbSQ$J99E~01yXHQzp~^WRf?&j0X@8E)njP zko#cceDx86@sYdjyXj4634~z2ld*Z9rokIfh!FsoFx0|{c&LGJl%TO&2AKtogtNDo z9_Rg=E2HncHR5=?2i`Wxn+PAjB3H7Lixzc*A z_a`uu2(!p&T{j^HKsEAB&6iwCE|Y5~lFUcLn}-=dcgJ4W*M2xYhDer8<`aTxuh?`$ zNF|6NC9>B2X3~O3o9aB*3-n<$mkyB6&98jy}zYz~S^(_Chqr=funqvg00f!b$BDEH*~c|3h;({*M=S{Lu1Ji4grgD&A_U~G zbrB5T0hHl)FmM$jRBd@oC`Zj4=KC6;0e29Q1ArUgP-bZmfz#h_4MYHe9SmiBn_{?j zmNaxNZk?H82Qg__S-vfWKqLrq?|>L!L-z>7M93V5>T{GKZz-8W6)=j$*gboLh$W?A z1H5BO=70?7W3Gh61njPWh{JDVZ)bNJ)^6|^!!s9%0)a+%u`@t$Tumk-v0vDGvA6Fn z0F2>IqkGjChy?B)s07K(A{2m`0Fm6>w2yu%-a?@PbnHE%VX;8~o>C#Ah;lr=cmJho zt+jnz@3pt(<%@3Ha{avBZ%u1o7ol6`qxD7W8i=hm;%pig%`r+L=8Tb%HgDBB-R^5( zOmohFjH2VlbcE;`v#LR0-K@-0x3Io$%~oCVeC7#=ic?rsmKl>sJ_AM%R7Z2#TpUrT zM7UZ%o=?B{{)gkCP|yHcScF9oLDf?ly_1h+J662A4MjW=?CKN;A`%NY%m+?onAb7A zwTVn_#w_8w&qN5^jF|9kE{h})MhHBr5%}+p!FW&7V2HOq7b)B!V6U%6&A`OA!-XCQ zgbZ#TN|*-a)4dNy5WqMSg9&}io(A(EaNK|Z_LaV|pO1)cIuKPP95(MB0nv$g1ed6H z1W+>?P_HQxAg8bI1a?6I1{$ZqrBFa8W(XTw3W*?w6Zn|H1z?yP0*#C|L?XiQaSIJq zGnmJy)(}VWh_LhiMh&>1Qm{`k4G|&4O-GU^zEz357ft{!ZzOY|gkb?Y7&V$0HXBHQ zjo(S>kn-_(e24)1_Lr^deR-|hvfNf{*ZcKzSgV(3F4)$qL^lBD61z-;2oecRoFdJ{ zb-6Eq;RG8&!cra{KmPJp-%s--OaVU1zwxNXs0#qyiOJ1})!Oi{l87+dS<^$?C=BiVm}74Q zL)8$CImaFb zL^O=P2q{7bZs}ofkSLD*qyXr{4r?qUA5Oq-Mj-h1ZHD$22G~m&9&VjQOxqxrj#9?W z0nww68^FySJuFxlMTQt{`~dqV*ss)hgQWIiF(Ss$V6?b*ZHRjnaHV&ZfR#)Mme zGWa7zxYaGEl0}%9DVYvtC@2^KuG>b4B8&m8byFL|)@7@ll6EvE25Oy}Z);l-XrCHI zWRYL}gMawp!}o*&hy)n2<0gpcJ`_C2y9ZCW4Zv`3=yqKp4O38*c|J{fCZzD8%V20A&8>wpwO;++y_zy<6-vRh|$f6#l1s(ZNc5tfE;by6ug_q#V!vZf+6fA z9(M?tx)%@M$Njr={M&RLcX{WKrNLLI6?YQraON7DQ;-OQ_m*k6ppMZzj`8P!K@kUy zb+k7~-~kwF9gr|+I2F4Y4OR=pcqryJfW-j~jZ$Y=Tk;r3pup%-Vjxf4dncmUxA0zG z5e>l&sp^=;5eWjw@!>F^{PDe8eE9B%2wd-%Z%kF2wVQ4A_WB6`*ZW8lnD@^p`-BFVWq*^-cvvzoJB@LLco|whlL5tKDZih1p(a0sB8yV!vh!s zhii7cnHR_YQG%N@r|}HO4Kp4#?)wD*6W|abcpwH?O34vi6~{~*c%QsO+A)CuW=5p& zVXd&!gZ&L=AjK{GwcD5ZNxEYCza@$l#@;O+sq2iZG7gxTnw#}t?lXgC$~J|cLt0ShETGuT<3!)FV^&Bn*&q3+=Z z1Y`iJmNQ}CDAXxZ#7KZfh_}SFQN=;Ta9SPLl?M{-VDo5A!hDP&NOq;s9`HDpJyMtl zFw+Py+#8j6DPrsv+`~Y2Fue^B$KaU= z2NB(|<8Zm$rx`v{qz0z|5t-BIrwhq6KZHNH_eaC7ZCx+@UT^Ci0qXq=Y>U^;wl#EJ zRWlVN<`UhS*2pQDaexFOrPLJNy#NMu42rPL9H0=EZ@&5AFaF{mKR$jOGfhSssVsnd z(Y(Vd3}%F=s``cte;t+P@llOdGo>P@58oim;Oz_ueV8W>9vJT9Mi>$;P|Ue?Y{Mb?y!T-qlzr z+>tom{2qNcsSKhU4sryI;hBdIzEMQj*eVDJJFGmgnE_x7mS5~KMd)sB#v{r;R@&hLyYlet6{jSm&On~a4=dSP$&Xo;9+8*{uNtn6 ziB#2e)G?w!+j8~5+f^ZmOaAVg@BjLr{L^3j@asIy001$b^{_0E0T>JqELCG31@;Ju z^Kp+ML|4ZF9s`R|g#G^kKOI69Po_|^0000kbVXQnV{dJ3Wo~o;AVX3`K~zstIv__$ tO;8|EPE8<2X>4?5av)Y^a&u{KZXhu(F$y^4;+Fsb002ovPDHLkV1l~3Y~%m{ literal 0 HcmV?d00001 diff --git a/tests/utils.py b/tests/utils.py index b6c49520..bcf0dbdc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -17,9 +17,10 @@ def get_image_file(): http://en.wikipedia.org/wiki/Lenna http://sipi.usc.edu/database/database.php?volume=misc&image=12 - + https://lintian.debian.org/tags/license-problem-non-free-img-lenna.html + https://github.com/libav/libav/commit/8895bf7b78650c0c21c88cec0484e138ec511a4b """ - path = os.path.join(settings.MEDIA_ROOT, 'lenna.png') + path = os.path.join(settings.MEDIA_ROOT, 'reference.png') return open(path, 'r+b') From 371a3bb3760f244c181eb24eeec9408c940bcc1e Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 25 Feb 2016 01:23:39 +0200 Subject: [PATCH 408/527] Drop support for older Django and Python versions This change drop official support for Django 1.2 and 1.3 and Python 2.6 and 3.2 In this commit test requirements are not so strict to allow versions available in Debian sid. Fixes #362 Many thanks to @fladi --- .travis.yml | 16 ++++-------- setup.py | 15 +++++------ tox.ini | 73 ++++++----------------------------------------------- 3 files changed, 20 insertions(+), 84 deletions(-) diff --git a/.travis.yml b/.travis.yml index 563884a3..45a1efd5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,6 @@ python: "2.7" sudo: false env: - - TOX_ENV=py26-django12 - - TOX_ENV=py26-django13 - - TOX_ENV=py26-django14 - - TOX_ENV=py26-django15 - - TOX_ENV=py26-django16 - TOX_ENV=py27-django12 - TOX_ENV=py27-django13 - TOX_ENV=py27-django14 @@ -16,10 +11,6 @@ env: - TOX_ENV=py27-django17 - TOX_ENV=py27-django18 - TOX_ENV=py27-django19 - - TOX_ENV=py32-django15 - - TOX_ENV=py32-django16 - - TOX_ENV=py32-django17 - - TOX_ENV=py32-django18 - TOX_ENV=py33-django15 - TOX_ENV=py33-django16 - TOX_ENV=py33-django17 @@ -28,13 +19,16 @@ env: - TOX_ENV=py34-django17 - TOX_ENV=py34-django18 - TOX_ENV=py34-django19 + - TOX_ENV=py35-django18 - TOX_ENV=py35-django19 matrix: - # Python 3.5 not yet available on travis, watch this to see when it is. fast_finish: true + # Python 3.5 not yet available on travis, watch this to see when it is. allow_failures: - - env: TOX_ENV=py35-django19 + - env: + - TOX_ENV=py35-django18 + - TOX_ENV=py35-django19 install: - pip install tox --use-mirrors diff --git a/setup.py b/setup.py index 618225a1..3e1408b4 100644 --- a/setup.py +++ b/setup.py @@ -43,12 +43,12 @@ def exec_file(filepath, globalz=None, localz=None): zip_safe=False, include_package_data=True, tests_require=[ - 'beautifulsoup4==4.4.0', - 'nose>=1.3.6,<1.5', - 'nose-progressive==1.5.1', - 'django-nose>=1.2,<1.5', - 'Pillow<3.0', - 'mock==1.0.1', + 'beautifulsoup4>=4.4.0', + 'nose>=1.3.6', + 'nose-progressive>=1.5.1', + 'django-nose>=1.4', + 'Pillow', + 'mock>=1.0.1', ], test_suite='testrunner.run_tests', install_requires=[ @@ -68,12 +68,11 @@ def exec_file(filepath, globalz=None, localz=None): 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', 'Topic :: Utilities' ], ) diff --git a/tox.ini b/tox.ini index e73b8cd6..673927b7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,9 @@ [tox] envlist = - py35-django19, + py35-django19, py35-django18, py34-django19, py34-django18, py34-django17, py34-django16, py33-django18, py33-django17, py33-django16, py33-django15, - py32-django18, py32-django17, py32-django16, py32-django15, - py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, - py26-django16, py26-django15, py26-django14, py26-django13, py26-django12 + py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, [testenv] commands = python setup.py test @@ -16,6 +14,12 @@ deps = Django>=1.9,<1.10 django-nose==1.4.2 +[testenv:py35-django18] +basepython = python3.5 +deps = + Django>=1.8,<1.9 + django-nose==1.4.2 + [testenv:py34-django19] basepython = python3.4 deps = @@ -61,28 +65,6 @@ basepython = python3.3 deps = Django>=1.5,<1.6 -[testenv:py32-django18] -basepython = python3.4 -deps = - Django>=1.8,<1.9 - django-nose==1.4.2 - -[testenv:py32-django17] -basepython = python3.4 -deps = - Django>=1.7,<1.8 - django-nose==1.4 - -[testenv:py32-django16] -basepython = python3.2 -deps = - Django>=1.6,<1.7 - -[testenv:py32-django15] -basepython = python3.2 -deps = - Django>=1.5,<1.6 - [testenv:py27-django19] basepython = python2.7 deps = @@ -115,42 +97,3 @@ deps = basepython = python2.7 deps = Django>=1.4,<1.5 - -[testenv:py27-django13] -basepython = python2.7 -deps = - Django>=1.3,<1.4 - django-nose==1.2 - -[testenv:py27-django12] -basepython = python2.7 -deps = - Django>=1.2,<1.3 - django-nose==1.2 - -[testenv:py26-django16] -basepython = python2.6 -deps = - Django>=1.6,<1.7 - -[testenv:py26-django15] -basepython = python2.6 -deps = - Django>=1.5,<1.6 - -[testenv:py26-django14] -basepython = python2.6 -deps = - Django>=1.4,<1.5 - -[testenv:py26-django13] -basepython = python2.6 -deps = - Django>=1.3,<1.4 - django-nose==1.2 - -[testenv:py26-django12] -basepython = python2.6 -deps = - Django>=1.2,<1.3 - django-nose==1.2 From b460a668747e3fcd7a7bfffc702a3eb4a3f051c7 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 25 Feb 2016 01:45:58 +0200 Subject: [PATCH 409/527] Make travis happy --- .travis.yml | 70 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45a1efd5..b9824e8a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,40 +1,50 @@ + language: python -python: "2.7" + sudo: false -env: - - TOX_ENV=py27-django12 - - TOX_ENV=py27-django13 - - TOX_ENV=py27-django14 - - TOX_ENV=py27-django15 - - TOX_ENV=py27-django16 - - TOX_ENV=py27-django17 - - TOX_ENV=py27-django18 - - TOX_ENV=py27-django19 - - TOX_ENV=py33-django15 - - TOX_ENV=py33-django16 - - TOX_ENV=py33-django17 - - TOX_ENV=py33-django18 - - TOX_ENV=py34-django16 - - TOX_ENV=py34-django17 - - TOX_ENV=py34-django18 - - TOX_ENV=py34-django19 - - TOX_ENV=py35-django18 - - TOX_ENV=py35-django19 +install: + - pip install tox + +script: + - tox matrix: fast_finish: true - # Python 3.5 not yet available on travis, watch this to see when it is. - allow_failures: - - env: - - TOX_ENV=py35-django18 - - TOX_ENV=py35-django19 - -install: - - pip install tox --use-mirrors + include: + - env: TOXENV=py27-django14 + python: 2.7 + - env: TOXENV=py27-django15 + python: 2.7 + - env: TOXENV=py27-django16 + python: 2.7 + - env: TOXENV=py27-django17 + python: 2.7 + - env: TOXENV=py27-django18 + python: 2.7 + - env: TOXENV=py27-django19 + python: 2.7 + - env: TOXENV=py33-django15 + python: 3.3 + - env: TOXENV=py33-django16 + python: 3.3 + - env: TOXENV=py33-django17 + python: 3.3 + - env: TOXENV=py33-django18 + python: 3.3 + - env: TOXENV=py34-django16 + python: 3.4 + - env: TOXENV=py34-django17 + python: 3.4 + - env: TOXENV=py34-django18 + python: 3.4 + - env: TOXENV=py34-django19 + python: 3.4 + - env: TOXENV=py35-django18 + python: 3.5 + - env: TOXENV=py35-django19 + python: 3.5 -script: - - tox -e $TOX_ENV notifications: irc: "irc.freenode.org#imagekit" From f2255a5d3a2c68da36be2dbd6ce8064576f8f577 Mon Sep 17 00:00:00 2001 From: Michael Fladischer Date: Tue, 9 Feb 2016 11:13:58 +0100 Subject: [PATCH 410/527] Include the test suite in the sourcetarball but do not install it. I reworked the `MANIFEST.in` to include the whole test suite so it can be used by distribution packages during build time. It is excluded from the installed packages automatically. The inclusion rules for the documentation were also made more verbose to prevent build artifacts from entering the source tarball (think .pyc files). --- MANIFEST.in | 17 ++++++++++++++--- setup.py | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 94be0c57..a0efbf6c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,17 @@ include AUTHORS include LICENSE include README.rst -recursive-include docs * -recursive-include imagekit/templates * -prune tests +include testrunner.py +include tests/*.py +include tests/assets/Lenna.png +include tests/assets/lenna-*.jpg +include tests/media/lenna.png +prune tests/media/CACHE +prune tests/media/b +prune tests/media/photos +include docs/Makefile +include docs/conf.py +include docs/make.bat +include docs/*.rst +recursive-include docs/_themes LICENSE README.rst flask_theme_support.py theme.conf *.css_t *.css *.html +recursive-include imagekit/templates *.html diff --git a/setup.py b/setup.py index 3e1408b4..e2f34d0a 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ def exec_file(filepath, globalz=None, localz=None): maintainer_email='bryan@revyver.com', license='BSD', url='http://github.com/matthewwithanm/django-imagekit/', - packages=find_packages(), + packages=find_packages(exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']), zip_safe=False, include_package_data=True, tests_require=[ From f98ee822a4a60bc56fe2b777c7ecd844fade8b55 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sat, 9 Jul 2016 14:23:42 +0300 Subject: [PATCH 411/527] Ignore .idea from git --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c571f485..584a38f0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.pyc .DS_Store .tox +.idea MANIFEST build dist From 5cde74e3e215df5b6ade3e412a1ee7ae416cbdb2 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Mon, 11 Jul 2016 01:34:50 +0300 Subject: [PATCH 412/527] Fixes #379 Support for Django 1.10 --- imagekit/forms/fields.py | 6 +++++- imagekit/utils.py | 17 +++++++---------- tests/settings.py | 21 +++++++++++++++++++-- tox.ini | 30 +++++++++++++++++++++++++++--- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index d032ff85..cf3ccba6 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -24,6 +24,10 @@ def clean(self, data, initial=None): if data and data != initial: spec = self.get_spec(source=data) - data = generate(spec) + f = generate(spec) + # Name is required in Django 1.4. When we drop support for it + # then we can dirrectly return the result from `generate(spec)` + f.name = data.name + return f return data diff --git a/imagekit/utils.py b/imagekit/utils.py index d768f570..fcbb4d44 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -132,16 +132,13 @@ def generate(generator): """ content = generator.generate() - - # If the file doesn't have a name, Django will raise an Exception while - # trying to save it, so we create a named temporary file. - if not getattr(content, 'name', None): - f = NamedTemporaryFile() - f.write(content.read()) - f.seek(0) - content = f - - return File(content) + f = File(content) + # The size of the File must be known or Django will try to open a file + # without a name and raise an Exception. + f.size = len(content.read()) + # After getting the size reset the file pointer for future reads. + content.seek(0) + return f def call_strategy_method(file, method_name): diff --git a/tests/settings.py b/tests/settings.py index 0c519896..dc3bb3c7 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -47,6 +47,23 @@ if os.getenv('TERM'): NOSE_ARGS.append('--with-progressive') -DEBUG = True -TEMPLATE_DEBUG = DEBUG CACHE_BACKEND = 'locmem://' + +# Django >= 1.8 +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.contrib.auth.context_processors.auth', + 'django.template.context_processors.debug', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', + 'django.template.context_processors.tz', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] diff --git a/tox.ini b/tox.ini index 673927b7..a76af7b5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,19 @@ [tox] envlist = - py35-django19, py35-django18, - py34-django19, py34-django18, py34-django17, py34-django16, + py35-django110, py35-django19, py35-django18, + py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, py33-django18, py33-django17, py33-django16, py33-django15, - py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, + py27-django110, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, [testenv] commands = python setup.py test +[testenv:py35-django110] +basepython = python3.5 +deps = + Django>=1.10b1,<1.11 + django-nose==1.4.4 + [testenv:py35-django19] basepython = python3.5 deps = @@ -20,6 +26,12 @@ deps = Django>=1.8,<1.9 django-nose==1.4.2 +[testenv:py34-django110] +basepython = python3.4 +deps = + Django>=1.10b1,<1.11 + django-nose==1.4.4 + [testenv:py34-django19] basepython = python3.4 deps = @@ -42,6 +54,7 @@ deps = basepython = python3.4 deps = Django>=1.6,<1.7 + django-nose<=1.4.2 [testenv:py33-django18] basepython = python3.3 @@ -59,11 +72,19 @@ deps = basepython = python3.3 deps = Django>=1.6,<1.7 + django-nose<=1.4.2 [testenv:py33-django15] basepython = python3.3 deps = Django>=1.5,<1.6 + django-nose==1.4 + +[testenv:py27-django110] +basepython = python2.7 +deps = + Django>=1.10b1,<1.11 + django-nose==1.4.4 [testenv:py27-django19] basepython = python2.7 @@ -87,13 +108,16 @@ deps = basepython = python2.7 deps = Django>=1.6,<1.7 + django-nose<=1.4.2 [testenv:py27-django15] basepython = python2.7 deps = Django>=1.5,<1.6 + django-nose==1.4 [testenv:py27-django14] basepython = python2.7 deps = Django>=1.4,<1.5 + django-nose==1.4 From 07d29b3bf7c0a32d07b36142cd40fea54ba01838 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 17 Jul 2016 04:43:04 +0300 Subject: [PATCH 413/527] Fixes #382: Tests no longer leave junk --- imagekit/cachefiles/backends.py | 3 +-- imagekit/utils.py | 4 ++-- testrunner.py | 3 +++ tests/test_generateimage_tag.py | 6 +++++- tests/test_serialization.py | 7 +++++-- tests/test_thumbnail_tag.py | 7 ++++++- tests/utils.py | 24 +++++++++++++++++++++++- 7 files changed, 45 insertions(+), 9 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index e615f2ea..bb0b7100 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -52,8 +52,7 @@ class CachedFileBackend(object): @property def cache(self): if not getattr(self, '_cache', None): - from django.conf import settings - self._cache = get_cache(settings.IMAGEKIT_CACHE_BACKEND) + self._cache = get_cache() return self._cache def get_key(self, file): diff --git a/imagekit/utils.py b/imagekit/utils.py index fcbb4d44..eb01c1c1 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -148,12 +148,12 @@ def call_strategy_method(file, method_name): fn(file) -def get_cache(backend, **kwargs): +def get_cache(backend=settings.IMAGEKIT_CACHE_BACKEND): try: from django.core.cache import caches except ImportError: from django.core.cache import get_cache - return get_cache(backend, **kwargs) + return get_cache(backend) return caches[backend] diff --git a/testrunner.py b/testrunner.py index e4d27c77..6b41b0fb 100644 --- a/testrunner.py +++ b/testrunner.py @@ -16,4 +16,7 @@ def run_tests(): cls = get_runner(settings) runner = cls() failures = runner.run_tests(['tests']) + # Clean autogenerated junk before exit + from tests.utils import clear_imagekit_test_files + clear_imagekit_test_files() sys.exit(failures) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index c39b7944..433c86f0 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,11 +1,12 @@ from django.template import TemplateSyntaxError from nose.tools import eq_, assert_false, raises, assert_not_equal from . import imagegenerators # noqa -from .utils import render_tag, get_html_attrs +from .utils import render_tag, get_html_attrs, clear_imagekit_cache def test_img_tag(): ttag = r"""{% generateimage 'testspec' source=img %}""" + clear_imagekit_cache() attrs = get_html_attrs(ttag) expected_attrs = set(['src', 'width', 'height']) eq_(set(attrs.keys()), expected_attrs) @@ -15,6 +16,7 @@ def test_img_tag(): def test_img_tag_attrs(): ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" %}""" + clear_imagekit_cache() attrs = get_html_attrs(ttag) eq_(attrs.get('alt'), 'Hello') @@ -42,11 +44,13 @@ def test_single_dimension_attr(): """ ttag = r"""{% generateimage 'testspec' source=img -- width="50" %}""" + clear_imagekit_cache() attrs = get_html_attrs(ttag) assert_false('height' in attrs) def test_assignment_tag(): ttag = r"""{% generateimage 'testspec' source=img as th %}{{ th.url }}""" + clear_imagekit_cache() html = render_tag(ttag) assert_not_equal(html.strip(), '') diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 9b68af93..b995658d 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -6,10 +6,11 @@ from imagekit.cachefiles import ImageCacheFile from .imagegenerators import TestSpec -from .utils import create_photo, pickleback, get_unique_image_file +from .utils import create_photo, pickleback, get_unique_image_file, clear_imagekit_cache def test_imagespecfield(): + clear_imagekit_cache() instance = create_photo('pickletest2.jpg') thumbnail = pickleback(instance.thumbnail) thumbnail.generate() @@ -22,12 +23,14 @@ def test_circular_ref(): This corresponds to #234 """ + clear_imagekit_cache() instance = create_photo('pickletest3.jpg') instance.thumbnail # Cause thumbnail to be added to instance's __dict__ pickleback(instance) - + def test_cachefiles(): + clear_imagekit_cache() spec = TestSpec(source=get_unique_image_file()) file = ImageCacheFile(spec) file.url diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index e31304af..c9382241 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,11 +1,12 @@ from django.template import TemplateSyntaxError from nose.tools import eq_, raises, assert_not_equal from . import imagegenerators # noqa -from .utils import render_tag, get_html_attrs +from .utils import render_tag, get_html_attrs, clear_imagekit_cache def test_img_tag(): ttag = r"""{% thumbnail '100x100' img %}""" + clear_imagekit_cache() attrs = get_html_attrs(ttag) expected_attrs = set(['src', 'width', 'height']) eq_(set(attrs.keys()), expected_attrs) @@ -15,6 +16,7 @@ def test_img_tag(): def test_img_tag_attrs(): ttag = r"""{% thumbnail '100x100' img -- alt="Hello" %}""" + clear_imagekit_cache() attrs = get_html_attrs(ttag) eq_(attrs.get('alt'), 'Hello') @@ -50,17 +52,20 @@ def test_html_attrs_assignment(): def test_assignment_tag(): ttag = r"""{% thumbnail '100x100' img as th %}{{ th.url }}""" + clear_imagekit_cache() html = render_tag(ttag) assert_not_equal(html, '') def test_single_dimension(): ttag = r"""{% thumbnail '100x' img as th %}{{ th.width }}""" + clear_imagekit_cache() html = render_tag(ttag) eq_(html, '100') def test_alternate_generator(): ttag = r"""{% thumbnail '1pxsq' '100x' img as th %}{{ th.width }}""" + clear_imagekit_cache() html = render_tag(ttag) eq_(html, '1') diff --git a/tests/utils.py b/tests/utils.py index bcf0dbdc..8b16a09a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,10 +1,12 @@ from bs4 import BeautifulSoup import os -from django.conf import settings +import shutil from django.core.files import File from django.template import Context, Template from imagekit.cachefiles.backends import Simple, CacheFileState +from imagekit.conf import settings from imagekit.lib import Image, StringIO +from imagekit.utils import get_cache from nose.tools import assert_true, assert_false import pickle from tempfile import NamedTemporaryFile @@ -82,3 +84,23 @@ class DummyAsyncCacheFileBackend(Simple): def generate(self, file, force=False): pass + + +def clear_imagekit_cache(): + cache = get_cache() + cache.clear() + # Clear IMAGEKIT_CACHEFILE_DIR + cache_dir = os.path.join(settings.MEDIA_ROOT, settings.IMAGEKIT_CACHEFILE_DIR) + if os.path.exists(cache_dir): + shutil.rmtree(cache_dir) + + +def clear_imagekit_test_files(): + clear_imagekit_cache() + for fname in os.listdir(settings.MEDIA_ROOT): + if fname != 'reference.png': + path = os.path.join(settings.MEDIA_ROOT, fname) + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) From d86ec082f1e6f3be36d7e9a6132c5d02c43abbed Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 17 Jul 2016 05:08:01 +0300 Subject: [PATCH 414/527] Fixed #350: Error when trying to access width/height after url If the file is closed and something is calling `open` now the file will be opened correctly event if it was already closed --- imagekit/files.py | 13 ++++++++++++- tests/test_generateimage_tag.py | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index e7178880..84fa544f 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -56,7 +56,18 @@ def _get_size(self): def open(self, mode='rb'): self._require_file() - self.file.open(mode) + try: + self.file.open(mode) + except ValueError: + # if the underlaying file can't be reopened + # then we will use the storage to try to open it again + if self.file.closed: + # clear cached file instance + del self.file + # Because file is a property we can acces it after + # we deleted it + return self.file.open(mode) + raise def _get_closed(self): file = getattr(self, '_file', None) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 433c86f0..db3f5772 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -50,7 +50,7 @@ def test_single_dimension_attr(): def test_assignment_tag(): - ttag = r"""{% generateimage 'testspec' source=img as th %}{{ th.url }}""" + ttag = r"""{% generateimage 'testspec' source=img as th %}{{ th.url }}{{ th.height }}{{ th.width }}""" clear_imagekit_cache() html = render_tag(ttag) assert_not_equal(html.strip(), '') From 3c0c47d8ed3bfd9efd0ee3e2b7cd18b69ef681e7 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 17 Jul 2016 05:23:13 +0300 Subject: [PATCH 415/527] Ignore VSCode workspace config files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 584a38f0..37054fa8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .DS_Store .tox .idea +.vscode MANIFEST build dist From f1f295e054fea72514f3dfa462a0c9d9ef2b53d7 Mon Sep 17 00:00:00 2001 From: Hannes Tismer Date: Mon, 24 Oct 2016 16:21:53 +0200 Subject: [PATCH 416/527] honor post_save's update_fields and only fire the source_saved signal when needed --- imagekit/specs/sourcegroups.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index d8ea3a7f..03a33224 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -87,12 +87,15 @@ def get_source_fields(self, instance): if isinstance(instance, src.model_class)) @ik_model_receiver - def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): + def post_save_receiver(self, sender, instance=None, created=False, update_fields=None, raw=False, **kwargs): if not raw: self.init_instance(instance) old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) for attname in self.get_source_fields(instance): + if update_fields and attname not in update_fields: + continue + file = getattr(instance, attname) if file and old_hashes.get(attname) != new_hashes[attname]: self.dispatch_signal(source_saved, file, sender, instance, From c354bb365aa7520ecb4d9cd11f07d0675b5c2250 Mon Sep 17 00:00:00 2001 From: Sobolev Nikita Date: Sat, 5 Nov 2016 20:47:32 +0300 Subject: [PATCH 417/527] updated readme.rst with a svg badge --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index bb3bb002..84ec2944 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ |Build Status|_ -.. |Build Status| image:: https://travis-ci.org/matthewwithanm/django-imagekit.png?branch=develop +.. |Build Status| image:: https://travis-ci.org/matthewwithanm/django-imagekit.svg?branch=develop .. _Build Status: https://travis-ci.org/matthewwithanm/django-imagekit ImageKit is a Django app for processing images. Need a thumbnail? A From 95e484d07372cb01f83f7d5024256e947ce956ec Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 9 Feb 2017 00:43:08 +0200 Subject: [PATCH 418/527] Cleanup caching configuration Requires Django 1.3+ --- imagekit/conf.py | 27 ++++++--------------------- imagekit/utils.py | 7 ++++--- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 84dffb6b..88af0721 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -1,5 +1,6 @@ from appconf import AppConf from django.conf import settings +from django.core.exceptions import ImproperlyConfigured class ImageKitConf(AppConf): @@ -17,27 +18,11 @@ class ImageKitConf(AppConf): def configure_cache_backend(self, value): if value is None: - # DEFAULT_CACHE_ALIAS doesn't exist in Django<=1.2 - try: - from django.core.cache import DEFAULT_CACHE_ALIAS as default_cache_alias - except ImportError: - default_cache_alias = 'default' - - caches = getattr(settings, 'CACHES', None) - if caches is None: - # Support Django<=1.2 there is no default `CACHES` setting - try: - from django.core.cache.backends.dummy import DummyCache - except ImportError: - dummy_cache = 'dummy://' - else: - dummy_cache = 'django.core.cache.backends.dummy.DummyCache' - return dummy_cache - - if default_cache_alias in caches: - value = default_cache_alias - else: - raise ValueError("The default cache alias '%s' is not available in CACHES" % default_cache_alias) + from django.core.cache import DEFAULT_CACHE_ALIAS + return DEFAULT_CACHE_ALIAS + + if value not in settings.CACHES: + raise ImproperlyConfigured("{0} is not present in settings.CACHES".format(value)) return value diff --git a/imagekit/utils.py b/imagekit/utils.py index eb01c1c1..61caecb8 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -148,14 +148,15 @@ def call_strategy_method(file, method_name): fn(file) -def get_cache(backend=settings.IMAGEKIT_CACHE_BACKEND): +def get_cache(): try: from django.core.cache import caches except ImportError: + # Django < 1.7 from django.core.cache import get_cache - return get_cache(backend) + return get_cache(settings.IMAGEKIT_CACHE_BACKEND) - return caches[backend] + return caches[settings.IMAGEKIT_CACHE_BACKEND] def sanitize_cache_key(key): From 732f7045e43c148891b8777dce675b1f8fff818e Mon Sep 17 00:00:00 2001 From: rohit suri Date: Wed, 15 Feb 2017 21:24:32 -0800 Subject: [PATCH 419/527] Close the file only if it has been opened locally --- imagekit/specs/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 829dce1f..1ef298e1 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -143,6 +143,7 @@ def generate(self): raise MissingSource("The spec '%s' has no source file associated" " with it." % self) + file_opened_locally = False # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) try: @@ -151,12 +152,14 @@ def generate(self): # Re-open the file -- https://code.djangoproject.com/ticket/13750 self.source.open() + file_opened_locally = True img = open_image(self.source) new_image = process_image(img, processors=self.processors, format=self.format, autoconvert=self.autoconvert, options=self.options) - self.source.close() + if file_opened_locally: + self.source.close() return new_image From 48cf03b482103fd66f2937b57ea950af2199af1e Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 16 Feb 2017 13:57:16 +0200 Subject: [PATCH 420/527] Test against Django 1.11 --- .travis.yml | 12 ++++++++++++ tox.ini | 30 ++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9824e8a..b8528b43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,10 @@ matrix: python: 2.7 - env: TOXENV=py27-django19 python: 2.7 + - env: TOXENV=py27-django110 + python: 2.7 + - env: TOXENV=py27-django111 + python: 2.7 - env: TOXENV=py33-django15 python: 3.3 - env: TOXENV=py33-django16 @@ -40,10 +44,18 @@ matrix: python: 3.4 - env: TOXENV=py34-django19 python: 3.4 + - env: TOXENV=py34-django110 + python: 3.4 + - env: TOXENV=py34-django111 + python: 3.4 - env: TOXENV=py35-django18 python: 3.5 - env: TOXENV=py35-django19 python: 3.5 + - env: TOXENV=py35-django110 + python: 3.5 + - env: TOXENV=py35-django111 + python: 3.5 notifications: diff --git a/tox.ini b/tox.ini index a76af7b5..9b127952 100644 --- a/tox.ini +++ b/tox.ini @@ -1,17 +1,23 @@ [tox] envlist = - py35-django110, py35-django19, py35-django18, - py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, + py35-django111, py35-django110, py35-django19, py35-django18, + py34-django111, py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, py33-django18, py33-django17, py33-django16, py33-django15, - py27-django110, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, + py27-django111, py27-django110, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, [testenv] commands = python setup.py test +[testenv:py35-django111] +basepython = python3.5 +deps = + Django>=1.11a1,<1.12 + django-nose==1.4.4 + [testenv:py35-django110] basepython = python3.5 deps = - Django>=1.10b1,<1.11 + Django>=1.10,<1.11 django-nose==1.4.4 [testenv:py35-django19] @@ -26,10 +32,16 @@ deps = Django>=1.8,<1.9 django-nose==1.4.2 +[testenv:py34-django111] +basepython = python3.4 +deps = + Django>=1.11a1,<1.12 + django-nose==1.4.4 + [testenv:py34-django110] basepython = python3.4 deps = - Django>=1.10b1,<1.11 + Django>=1.10,<1.11 django-nose==1.4.4 [testenv:py34-django19] @@ -80,10 +92,16 @@ deps = Django>=1.5,<1.6 django-nose==1.4 +[testenv:py27-django111] +basepython = python2.7 +deps = + Django>=1.11a1,<1.12 + django-nose==1.4.4 + [testenv:py27-django110] basepython = python2.7 deps = - Django>=1.10b1,<1.11 + Django>=1.10,<1.11 django-nose==1.4.4 [testenv:py27-django19] From 4d1ee41f2e6f86fdb1d9add0ee04e3d8cd0f2ffb Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 9 Feb 2017 00:44:32 +0200 Subject: [PATCH 421/527] Make it possible to configure IMAGEKIT_CACHE_TIMEOUT By default cache forever --- docs/caching.rst | 22 +++++++++++++++------- docs/configuration.rst | 9 +++++++++ imagekit/cachefiles/backends.py | 3 ++- imagekit/conf.py | 8 ++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/docs/caching.rst b/docs/caching.rst index 6aa7a1e1..4e2b8a91 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -100,13 +100,21 @@ ImageKit. Each has its own pros and cons. Caching Data About Generated Files ---------------------------------- -The easiest, and most significant improvement you can make to improve the -performance of your site is to have ImageKit cache the state of your generated -files. The default cache file backend will already do this (if ``DEBUG`` is -``False``), using your default Django cache backend, but you can make it way -better by setting ``IMAGEKIT_CACHE_BACKEND``. Generally, once a file is -generated, you will never be removing it; therefore, if you can, you should set -``IMAGEKIT_CACHE_BACKEND`` to a cache backend that will cache forever. +Generally, once a file is generated, you will never be removing it, so by +default ImageKit will use default cache to cache the state of generated +files "forever" (or only 5 minutes when ``DEBUG = True``). + +The time for which ImageKit will cache state is configured with +``IMAGEKIT_CACHE_TIMEOUT``. If set to ``None`` this means "never expire" +(default when ``DEBUG = False``). You can reduce this timeout if you want +or set it to some numeric value in seconds if your cache backend behaves +differently and for example do not cache values if timeout is ``None``. + +If you clear your cache durring deployment or some other reason probably +you do not want to lose the cache for generated images especcialy if you +are using some slow remote storage (like Amazon S3). Then you can configure +seprate cache (for example redis) in your ``CACHES`` config and tell ImageKit +to use it instead of the default cache by setting ``IMAGEKIT_CACHE_BACKEND``. Pre-Generating Images diff --git a/docs/configuration.rst b/docs/configuration.rst index f65ed526..236191e3 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -55,6 +55,15 @@ Settings .. _`Django cache section`: https://docs.djangoproject.com/en/1.8/topics/cache/#accessing-the-cache +.. attribute:: IMAGEKIT_CACHE_TIMEOUT + + :default: ``None`` + + Use when you need to override the timeout used to cache file state. + By default it is "cache forever". + It's highly recommended that you use a very high timeout. + + .. attribute:: IMAGEKIT_CACHE_PREFIX :default: ``'imagekit:'`` diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index bb0b7100..e006dc80 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -2,6 +2,7 @@ import warnings from copy import copy from django.core.exceptions import ImproperlyConfigured +from django.conf import settings class CacheFileState(object): @@ -74,7 +75,7 @@ def set_state(self, file, state): if state == CacheFileState.DOES_NOT_EXIST: self.cache.set(key, state, self.existence_check_timeout) else: - self.cache.set(key, state) + self.cache.set(key, state, settings.IMAGEKIT_CACHE_TIMEOUT) def __getstate__(self): state = copy(self.__dict__) diff --git a/imagekit/conf.py b/imagekit/conf.py index 88af0721..9d2ca1f3 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -14,6 +14,7 @@ class ImageKitConf(AppConf): CACHE_BACKEND = None CACHE_PREFIX = 'imagekit:' + CACHE_TIMEOUT = None USE_MEMCACHED_SAFE_CACHE_KEY = True def configure_cache_backend(self, value): @@ -26,6 +27,13 @@ def configure_cache_backend(self, value): return value + def configure_cache_timeout(self, value): + if value is None and settings.DEBUG: + # If value is not configured and is DEBUG set it to 5 minutes + return 300 + # Otherwise leave it as is. If it is None then valies will never expire + return value + def configure_default_file_storage(self, value): if value is None: value = settings.DEFAULT_FILE_STORAGE From 2bc6241f55f0f405f44615bb95bf1d1f35cf1d33 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Tue, 21 Feb 2017 15:19:40 +0200 Subject: [PATCH 422/527] Do not try south modelinspector when not needed Fixed #408 --- imagekit/models/fields/__init__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 2543f905..04a65460 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +from django.conf import settings from django.db import models from django.db.models.signals import class_prepared from .files import ProcessedImageFieldFile @@ -111,9 +112,11 @@ def contribute_to_class(self, cls, name): return super(ProcessedImageField, self).contribute_to_class(cls, name) -try: - from south.modelsinspector import add_introspection_rules -except ImportError: - pass -else: - add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$']) +# If the project does not use south, then we will not try to add introspection +if 'south' in settings.INSTALLED_APPS: + try: + from south.modelsinspector import add_introspection_rules + except ImportError: + pass + else: + add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$']) From 12fdee81dd06f3d25fe1de30f05a1c1495b9eea1 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 22 Feb 2017 13:28:11 +0200 Subject: [PATCH 423/527] Ignore autogenerated CTags file It used by some IDEs to index all Symbols in the project --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 37054fa8..7a5aeaa0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ dist /venv /venv3 /.env +/tags From 755193699b22be67364b1978914ba0a4e02829e2 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 22 Feb 2017 14:21:09 +0200 Subject: [PATCH 424/527] Replaces #301 autodiscover works with AppConfig --- imagekit/utils.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/imagekit/utils.py b/imagekit/utils.py index 61caecb8..27902c9a 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -69,6 +69,30 @@ def autodiscover(): """ global _autodiscovered + if _autodiscovered: + return + + try: + from django.utils.module_loading import autodiscover_modules + except ImportError: + # Django<1.7 + _autodiscover_modules_fallback() + else: + autodiscover_modules('imagegenerators') + + +def _autodiscover_modules_fallback(): + """ + Auto-discover INSTALLED_APPS imagegenerators.py modules and fail silently + when not present. This forces an import on them to register any admin bits + they may want. + + Copied from django.contrib.admin + + Used for Django versions < 1.7 + """ + global _autodiscovered + if _autodiscovered: return From 96383451a0df6fa1561021c8f9272c2763a6564f Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 22 Feb 2017 13:48:15 +0200 Subject: [PATCH 425/527] Universal wheels! --- MANIFEST.in | 1 + setup.cfg | 2 ++ setup.py | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 setup.cfg diff --git a/MANIFEST.in b/MANIFEST.in index a0efbf6c..b125b907 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,6 +2,7 @@ include AUTHORS include LICENSE include README.rst include testrunner.py +include setup.cfg include tests/*.py include tests/assets/Lenna.png include tests/assets/lenna-*.jpg diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..7c2b2874 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1 \ No newline at end of file diff --git a/setup.py b/setup.py index e2f34d0a..8244049a 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ if 'publish' in sys.argv: - os.system('python setup.py sdist upload') + os.system('python setup.py sdist bdist_wheel upload') sys.exit() From 46d2a9e663e1f85f3abed3f417de45129d09e68e Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 22 Feb 2017 15:35:20 +0200 Subject: [PATCH 426/527] Bump version to 4.0 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 5872ac01..9a389ab8 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.3' +__version__ = '4.0' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 934a5283ad823a5c637f875f07dcaf5eb617e2be Mon Sep 17 00:00:00 2001 From: mikob Date: Mon, 10 Apr 2017 17:46:29 +0900 Subject: [PATCH 427/527] Improved docs to include example on how to use plain ImageSpec (defined outside of model, not ImageSpecField) with AdminThumbnail. --- README.rst | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.rst b/README.rst index 84ec2944..23d26ac3 100644 --- a/README.rst +++ b/README.rst @@ -406,6 +406,37 @@ Django admin classes: admin.site.register(Photo, PhotoAdmin) +To use specs defined outside of models: + +.. code-block:: python + + from django.contrib import admin + from imagekit.admin import AdminThumbnail + from imagekit import ImageSpec + from imagekit.processors import ResizeToFill + from imagekit.cachefiles import ImageCacheFile + + from .models import Photo + + class AdminThumbnailSpec(ImageSpec): + processors = [ResizeToFill(100, 30)] + format = 'JPEG' + options = {'quality': 60 } + + def cached_admin_thumb(model): + # `image` is the name of the image field on the model + cached = ImageCacheFile(AdminThumbnailSpec(model.image)) + # only generates the first time, subsequent calls use cache + cached.generate() + return cached + + class PhotoAdmin(admin.ModelAdmin): + list_display = ('__str__', 'admin_thumbnail') + admin_thumbnail = AdminThumbnail(image_field=cached_admin_thumb) + + admin.site.register(Photo, PhotoAdmin) + + AdminThumbnail can even use a custom template. For more information, see ``imagekit.admin.AdminThumbnail``. From 33a62b8840b51ca850cac2dad4d83e3d386eeed6 Mon Sep 17 00:00:00 2001 From: Tiago Almeida Date: Sun, 23 Apr 2017 16:25:13 -0300 Subject: [PATCH 428/527] Update advanced_usage.rst wrong attribute access... probally miss typed.. thumbnail dosent exists so i think its mode.thumbnail_height --- docs/advanced_usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index bb635e76..f02e122c 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -90,7 +90,7 @@ for getting this information. @property def processors(self): model, field_name = get_field_info(self.source) - return [ResizeToFill(model.thumbnail_width, thumbnail.avatar_height)] + return [ResizeToFill(model.thumbnail_width, model.thumbnail_height)] register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) From c24455ef36c36f0a844a98e692e60d6eaae15074 Mon Sep 17 00:00:00 2001 From: mikob Date: Wed, 10 May 2017 18:03:28 +0900 Subject: [PATCH 429/527] Update README.st change model->instance for clarity in defining specs outside of models. --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 23d26ac3..7d40b053 100644 --- a/README.rst +++ b/README.rst @@ -423,9 +423,9 @@ To use specs defined outside of models: format = 'JPEG' options = {'quality': 60 } - def cached_admin_thumb(model): + def cached_admin_thumb(instance): # `image` is the name of the image field on the model - cached = ImageCacheFile(AdminThumbnailSpec(model.image)) + cached = ImageCacheFile(AdminThumbnailSpec(instance.image)) # only generates the first time, subsequent calls use cache cached.generate() return cached From c74d8424b88c0bffe9a3d18cf09b33ea12ea4551 Mon Sep 17 00:00:00 2001 From: Moritz Pfeiffer Date: Tue, 16 May 2017 14:19:05 +0200 Subject: [PATCH 430/527] Added huge performance improvement by running imagekit.utils.autodiscover() only once on Django > 1.7 as it was intended. --- imagekit/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/utils.py b/imagekit/utils.py index 27902c9a..03a709ec 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -79,6 +79,7 @@ def autodiscover(): _autodiscover_modules_fallback() else: autodiscover_modules('imagegenerators') + _autodiscovered = True def _autodiscover_modules_fallback(): From 36fa53e249726f88090de24bb6834f2c3285675a Mon Sep 17 00:00:00 2001 From: Moritz Pfeiffer Date: Wed, 17 May 2017 09:51:24 +0200 Subject: [PATCH 431/527] Cleaned up _autodiscovered flag handling. --- imagekit/utils.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 03a709ec..ca6727ae 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -79,7 +79,7 @@ def autodiscover(): _autodiscover_modules_fallback() else: autodiscover_modules('imagegenerators') - _autodiscovered = True + _autodiscovered = True def _autodiscover_modules_fallback(): @@ -92,11 +92,6 @@ def _autodiscover_modules_fallback(): Used for Django versions < 1.7 """ - global _autodiscovered - - if _autodiscovered: - return - from django.conf import settings try: from importlib import import_module @@ -104,8 +99,6 @@ def _autodiscover_modules_fallback(): from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule - _autodiscovered = True - for app in settings.INSTALLED_APPS: # As of Django 1.7, settings.INSTALLED_APPS may contain classes instead of modules, hence the try/except # See here: https://docs.djangoproject.com/en/dev/releases/1.7/#introspecting-applications From f96dadbfe0f405282cd256390746eaf6bb9fd0af Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 17 May 2017 17:45:22 +0300 Subject: [PATCH 432/527] Bump version to 4.0.1 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 9a389ab8..6c9eefe4 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '4.0' +__version__ = '4.0.1' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 681b85d7bffbae3fa9518088ff84585d3562b97a Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 17 May 2017 18:12:57 +0300 Subject: [PATCH 433/527] stylling and linting fixes to setup.py --- setup.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 8244049a..2af1ad58 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#/usr/bin/env python +#!/usr/bin/env python import codecs import os from setuptools import setup, find_packages @@ -7,7 +7,7 @@ # Workaround for multiprocessing/nose issue. See http://bugs.python.org/msg170215 try: - import multiprocessing + import multiprocessing # NOQA except ImportError: pass @@ -19,13 +19,15 @@ read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read() + def exec_file(filepath, globalz=None, localz=None): exec(read(filepath), globalz, localz) + # Load package meta from the pkgmeta module without loading imagekit. pkgmeta = {} exec_file(os.path.join(os.path.dirname(__file__), - 'imagekit', 'pkgmeta.py'), pkgmeta) + 'imagekit', 'pkgmeta.py'), pkgmeta) setup( From 2b04099dc48584baf24b794d0b3df9bd50667108 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 18 May 2017 23:38:32 +0300 Subject: [PATCH 434/527] Fixed #368 use specs directly in ProcessedImageField Thanks to @xcono for pointing to solution to the problem --- imagekit/models/fields/__init__.py | 6 +++++- tests/models.py | 11 +++++++++++ tests/test_fields.py | 14 +++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 04a65460..767374f2 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -93,7 +93,7 @@ class ProcessedImageField(models.ImageField, SpecHostField): def __init__(self, processors=None, format=None, options=None, verbose_name=None, name=None, width_field=None, height_field=None, - autoconvert=True, spec=None, spec_id=None, **kwargs): + autoconvert=None, spec=None, spec_id=None, **kwargs): """ The ProcessedImageField constructor accepts all of the arguments that the :class:`django.db.models.ImageField` constructor accepts, as well @@ -101,6 +101,10 @@ def __init__(self, processors=None, format=None, options=None, :class:`imagekit.models.ImageSpecField`. """ + # if spec is not provided then autoconvert will be True by default + if spec is None and autoconvert is None: + autoconvert = True + SpecHost.__init__(self, processors=processors, format=format, options=options, autoconvert=autoconvert, spec=spec, spec_id=spec_id) diff --git a/tests/models.py b/tests/models.py index 5667cad0..0f6bd0c4 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,10 +1,17 @@ from django.db import models +from imagekit import ImageSpec from imagekit.models import ProcessedImageField from imagekit.models import ImageSpecField from imagekit.processors import Adjust, ResizeToFill, SmartCrop +class Thumbnail(ImageSpec): + processors = [ResizeToFill(100, 60)] + format = 'JPEG' + options = {'quality': 60} + + class ImageModel(models.Model): image = models.ImageField(upload_to='b') @@ -27,6 +34,10 @@ class ProcessedImageFieldModel(models.Model): options={'quality': 90}, upload_to='p') +class ProcessedImageFieldWithSpecModel(models.Model): + processed = ProcessedImageField(spec=Thumbnail, upload_to='p') + + class CountingCacheFileStrategy(object): def __init__(self): self.on_existence_required_count = 0 diff --git a/tests/test_fields.py b/tests/test_fields.py index 6afb6cf7..96e73379 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -5,7 +5,9 @@ from imagekit.processors import SmartCrop from nose.tools import eq_ from . import imagegenerators # noqa -from .models import ProcessedImageFieldModel, ImageModel +from .models import (ProcessedImageFieldModel, + ProcessedImageFieldWithSpecModel, + ImageModel) from .utils import get_image_file @@ -19,6 +21,16 @@ def test_model_processedimagefield(): eq_(instance.processed.height, 50) +def test_model_processedimagefield_with_spec(): + instance = ProcessedImageFieldWithSpecModel() + file = File(get_image_file()) + instance.processed.save('whatever.jpeg', file) + instance.save() + + eq_(instance.processed.width, 100) + eq_(instance.processed.height, 60) + + def test_form_processedimagefield(): class TestForm(forms.ModelForm): image = ikforms.ProcessedImageField(spec_id='tests:testform_image', From 755bd34c3e7da9e6d76651d889155b10dcf8e8ca Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 31 May 2017 11:07:37 +0300 Subject: [PATCH 435/527] In Python 3 files should be opened as binary --- README.rst | 4 ++-- docs/advanced_usage.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 7d40b053..e6d91036 100644 --- a/README.rst +++ b/README.rst @@ -144,7 +144,7 @@ on, or what should be done with the result; that's up to you: .. code-block:: python - source_file = open('/path/to/myimage.jpg') + source_file = open('/path/to/myimage.jpg', 'rb') image_generator = Thumbnail(source=source_file) result = image_generator.generate() @@ -159,7 +159,7 @@ example, if you wanted to save it to disk: .. code-block:: python - dest = open('/path/to/dest.jpg', 'w') + dest = open('/path/to/dest.jpg', 'wb') dest.write(result.read()) dest.close() diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index bb635e76..37458c46 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -163,7 +163,7 @@ A simple example of a custom source group class is as follows: def files(self): os.chdir(self.dir) for name in glob.glob('*.jpg'): - yield open(name) + yield open(name, 'rb') Instances of this class could then be registered with one or more spec id: From 2e1b574486d3dce2924ab1a95b999133799e0704 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 24 Jul 2017 13:41:54 +0100 Subject: [PATCH 436/527] README - use Python 3 print function It's 2017!!! --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index e6d91036..d797561e 100644 --- a/README.rst +++ b/README.rst @@ -70,8 +70,8 @@ your model class: options={'quality': 60}) profile = Profile.objects.all()[0] - print profile.avatar_thumbnail.url # > /media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg - print profile.avatar_thumbnail.width # > 100 + print(profile.avatar_thumbnail.url) # > /media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg + print(profile.avatar_thumbnail.width) # > 100 As you can probably tell, ImageSpecFields work a lot like Django's ImageFields. The difference is that they're automatically generated by @@ -97,8 +97,8 @@ class: options={'quality': 60}) profile = Profile.objects.all()[0] - print profile.avatar_thumbnail.url # > /media/avatars/MY-avatar.jpg - print profile.avatar_thumbnail.width # > 100 + print(profile.avatar_thumbnail.url) # > /media/avatars/MY-avatar.jpg + print(profile.avatar_thumbnail.width) # > 100 This is pretty similar to our previous example. We don't need to specify a "source" any more since we're not processing another image field, but we do need From a153812add3f745e8de39630de509ee9b1dd54c6 Mon Sep 17 00:00:00 2001 From: Yuri Kanivetsky Date: Tue, 29 Aug 2017 11:27:10 +0300 Subject: [PATCH 437/527] generateimages: fix taking arguments --- imagekit/management/commands/generateimages.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 0d9cae5c..4983af3f 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -12,13 +12,15 @@ class Command(BaseCommand): "a:*:c" will match "a:b:c", but not "a:b:x:c", whereas "a:**:c" will match both. Subsegments are always matched, so "a" will match "a" as well as "a:b" and "a:b:c".""") - args = '[generator_ids]' + + def add_arguments(self, parser): + parser.add_argument('generator_id', nargs='*', help=':: for model specs') def handle(self, *args, **options): generators = generator_registry.get_ids() - if args: - patterns = self.compile_patterns(args) + if options['generator_id']: + patterns = self.compile_patterns(options['generator_id']) generators = (id for id in generators if any(p.match(id) for p in patterns)) for generator_id in generators: From de3047e73d813ec9a2e96381a3bda5a2cf19cd78 Mon Sep 17 00:00:00 2001 From: Yuri Kanivetsky Date: Tue, 12 Sep 2017 20:44:22 +0300 Subject: [PATCH 438/527] Make generateimages support pre Django 1.8 versions --- imagekit/management/commands/generateimages.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 4983af3f..2addfd31 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -12,6 +12,7 @@ class Command(BaseCommand): "a:*:c" will match "a:b:c", but not "a:b:x:c", whereas "a:**:c" will match both. Subsegments are always matched, so "a" will match "a" as well as "a:b" and "a:b:c".""") + args = '[generator_ids]' def add_arguments(self, parser): parser.add_argument('generator_id', nargs='*', help=':: for model specs') @@ -19,8 +20,9 @@ def add_arguments(self, parser): def handle(self, *args, **options): generators = generator_registry.get_ids() - if options['generator_id']: - patterns = self.compile_patterns(options['generator_id']) + generator_ids = options['generator_id'] if 'generator_id' in options else args + if generator_ids: + patterns = self.compile_patterns(generator_ids) generators = (id for id in generators if any(p.match(id) for p in patterns)) for generator_id in generators: From d80f426d3cbb24bbdb0d92cba3ba7f9484767104 Mon Sep 17 00:00:00 2001 From: Roman Gorbil Date: Tue, 10 Oct 2017 17:39:46 +0700 Subject: [PATCH 439/527] Fix `ImageCacheFile.__repr__` to not send signals Cachefile strategy may be configured to generate file when file existance required. To generate images, async backends passes `ImageCacheFile` instance to worker. Both celery and RQ calls `__repr__` method for each argument to enque call. And if `__repr__` of object will send `existnace_required` signal, we will get endless recursion. Issue: #434 --- imagekit/cachefiles/__init__.py | 6 ++++++ tests/test_cachefiles.py | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 2ba5cb8c..594df57c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -3,6 +3,7 @@ from django.core.files import File from django.core.files.images import ImageFile from django.utils.functional import SimpleLazyObject +from django.utils.encoding import smart_str from ..files import BaseIKFile from ..registry import generator_registry from ..signals import content_required, existence_required @@ -149,6 +150,11 @@ def __nonzero__(self): # Python 2 compatibility return self.__bool__() + def __repr__(self): + return smart_str("<%s: %s>" % ( + self.__class__.__name__, self if self.name else "None") + ) + class LazyImageCacheFile(SimpleLazyObject): def __init__(self, generator_id, *args, **kwargs): diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 8a93e716..ad01dda3 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,3 +1,4 @@ +import mock from django.conf import settings from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile @@ -48,6 +49,31 @@ def test_no_source_error(): file.generate() +def test_repr_does_not_send_existence_required(): + """ + Ensure that `__repr__` method does not send `existance_required` signal + + Cachefile strategy may be configured to generate file on + `existance_required`. + To generate images, backend passes `ImageCacheFile` instance to worker. + Both celery and RQ calls `__repr__` method for each argument to enque call. + And if `__repr__` of object will send this signal, we will get endless + recursion + + """ + with mock.patch('imagekit.cachefiles.existence_required') as signal: + # import here to apply mock + from imagekit.cachefiles import ImageCacheFile + + spec = TestSpec(source=get_unique_image_file()) + file = ImageCacheFile( + spec, + cachefile_backend=DummyAsyncCacheFileBackend() + ) + file.__repr__() + eq_(signal.send.called, False) + + def test_memcached_cache_key(): """ Ensure the default cachefile backend is sanitizing its cache key for From 6ee931398f3003c5e7a1a35b0ca8a99c49ac3012 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Fri, 17 Nov 2017 18:31:23 +0200 Subject: [PATCH 440/527] Do not leak open files after generation --- imagekit/specs/__init__.py | 27 +++++++++++++++------------ tests/test_closing_fieldfiles.py | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 tests/test_closing_fieldfiles.py diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 1ef298e1..d9339f37 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -143,23 +143,26 @@ def generate(self): raise MissingSource("The spec '%s' has no source file associated" " with it." % self) - file_opened_locally = False # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) - try: - img = open_image(self.source) - except ValueError: - # Re-open the file -- https://code.djangoproject.com/ticket/13750 + closed = self.source.closed + if closed: + # Django file object should know how to reopen itself if it was closed + # https://code.djangoproject.com/ticket/13750 self.source.open() - file_opened_locally = True - img = open_image(self.source) - new_image = process_image(img, processors=self.processors, - format=self.format, autoconvert=self.autoconvert, - options=self.options) - if file_opened_locally: - self.source.close() + try: + img = open_image(self.source) + new_image = process_image(img, + processors=self.processors, + format=self.format, + autoconvert=self.autoconvert, + options=self.options) + finally: + if closed: + # We need to close the file if it was opened by us + self.source.close() return new_image diff --git a/tests/test_closing_fieldfiles.py b/tests/test_closing_fieldfiles.py new file mode 100644 index 00000000..d8693c39 --- /dev/null +++ b/tests/test_closing_fieldfiles.py @@ -0,0 +1,25 @@ +from nose.tools import assert_false, assert_true + +from .models import Thumbnail +from .utils import create_photo + + +def test_do_not_leak_open_files(): + instance = create_photo('leak-test.jpg') + source_file = instance.original_image + # Ensure the FieldFile is closed before generation + source_file.close() + image_generator = Thumbnail(source=source_file) + image_generator.generate() + assert_true(source_file.closed) + + +def test_do_not_close_open_files_after_generate(): + instance = create_photo('do-not-close-test.jpg') + source_file = instance.original_image + # Ensure the FieldFile is opened before generation + source_file.open() + image_generator = Thumbnail(source=source_file) + image_generator.generate() + assert_false(source_file.closed) + source_file.close() From ea66e3d10d3d8d8cf221486b7b1df5d62f9c29f9 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Mon, 20 Nov 2017 10:24:12 +0200 Subject: [PATCH 441/527] Bump version to 4.0.2 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 6c9eefe4..afdaca40 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '4.0.1' +__version__ = '4.0.2' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 58e44975c7a2a08df02446cf8f0e48c1f981b38c Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Tue, 5 Dec 2017 22:44:40 +0200 Subject: [PATCH 442/527] Test against Django 2.0 --- .travis.yml | 4 ++++ tox.ini | 28 ++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index b8528b43..4fcb9fcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,6 +48,8 @@ matrix: python: 3.4 - env: TOXENV=py34-django111 python: 3.4 + - env: TOXENV=py34-django20 + python: 3.4 - env: TOXENV=py35-django18 python: 3.5 - env: TOXENV=py35-django19 @@ -56,6 +58,8 @@ matrix: python: 3.5 - env: TOXENV=py35-django111 python: 3.5 + - env: TOXENV=py35-django20 + python: 3.5 notifications: diff --git a/tox.ini b/tox.ini index 9b127952..653e3018 100644 --- a/tox.ini +++ b/tox.ini @@ -1,18 +1,24 @@ [tox] envlist = - py35-django111, py35-django110, py35-django19, py35-django18, - py34-django111, py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, + py35-django20, py35-django111, py35-django110, py35-django19, py35-django18, + py34-django20, py34-django111, py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, py33-django18, py33-django17, py33-django16, py33-django15, py27-django111, py27-django110, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, [testenv] commands = python setup.py test +[testenv:py35-django20] +basepython = python3.5 +deps = + Django>=2.0,<2.1 + django-nose==1.4.5 + [testenv:py35-django111] basepython = python3.5 deps = - Django>=1.11a1,<1.12 - django-nose==1.4.4 + Django>=1.11,<1.12 + django-nose==1.4.5 [testenv:py35-django110] basepython = python3.5 @@ -32,11 +38,17 @@ deps = Django>=1.8,<1.9 django-nose==1.4.2 +[testenv:py34-django20] +basepython = python3.4 +deps = + Django>=2.0,<2.1 + django-nose==1.4.5 + [testenv:py34-django111] basepython = python3.4 deps = - Django>=1.11a1,<1.12 - django-nose==1.4.4 + Django>=1.11,<1.12 + django-nose==1.4.5 [testenv:py34-django110] basepython = python3.4 @@ -95,8 +107,8 @@ deps = [testenv:py27-django111] basepython = python2.7 deps = - Django>=1.11a1,<1.12 - django-nose==1.4.4 + Django>=1.11,<1.12 + django-nose==1.4.5 [testenv:py27-django110] basepython = python2.7 From 595f7b35efa74640958a6eae55c4a401e59912ab Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 24 Apr 2018 09:48:43 -0300 Subject: [PATCH 443/527] Enhance condition in _get_size (#463) This fix the issue #326. --- imagekit/files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/files.py b/imagekit/files.py index 84fa544f..f64cf697 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -49,7 +49,7 @@ def _get_url(http://github.com/self): def _get_size(self): self._require_file() - if not self._committed: + if not getattr(self, '_committed', False): return self.file.size return self.storage.size(self.name) size = property(_get_size) From de991d404869fbf81a5ce5a2935c903b762b301f Mon Sep 17 00:00:00 2001 From: Roman Gorbil Date: Fri, 20 Oct 2017 18:26:37 +0700 Subject: [PATCH 444/527] Fix pickle serialization for ImageCacheFile When Celery CachedFileBackend used with filesystem storage (django.core.files.storage.FileSystemStorage), everything works fine. But there are issues with storages.backends.s3boto3.S3Boto3Storage (and it's fix from #391), as well as with django_s3_storage.storage.S3Storage. Exception was: ``` Traceback (most recent call last): ... File "/src/django-imagekit/imagekit/cachefiles/__init__.py", line 131, in __bool__ existence_required.send(sender=self, file=self) ... File "/libs/utils.py", line 380, in on_existence_required file.generate() File "/src/django-imagekit/imagekit/cachefiles/__init__.py", line 94, in generate self.cachefile_backend.generate(self, force) File "/src/django-imagekit/imagekit/cachefiles/backends.py", line 136, in generate self.schedule_generation(file, force=force) File "/src/django-imagekit/imagekit/cachefiles/backends.py", line 165, in schedule_generation _celery_task.delay(self, file.generator, force=force) ... File "/lib/python3.6/site-packages/kombu/serialization.py", line 221, in dumps payload = encoder(data) File "/lib/python3.6/site-packages/kombu/serialization.py", line 350, in pickle_dumps return dumper(obj, protocol=pickle_protocol) kombu.exceptions.EncodeError: can't pickle _thread._local objects ``` --- docs/caching.rst | 5 +++++ imagekit/cachefiles/__init__.py | 16 ++++++++++++++++ tests/test_serialization.py | 5 ++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/caching.rst b/docs/caching.rst index 4e2b8a91..8264089b 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -185,6 +185,11 @@ Or, in Python: def on_source_saved(self, file): file.generate() +.. note:: + + If you use custom storage backend for some specs, + (storage passed to the field different than configured one) + it's required the storage to be pickleable __ https://pypi.python.org/pypi/django-celery diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 594df57c..08ea04be 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -144,8 +144,24 @@ def __getstate__(self): # file is hidden link to "file" attribute state.pop('_file', None) + # remove storage from state as some non-FileSystemStorage can't be + # pickled + settings_storage = get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend' + ) + if state['storage'] == settings_storage: + state.pop('storage') return state + def __setstate__(self, state): + if 'storage' not in state: + state['storage'] = get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend' + ) + self.__dict__.update(state) + def __nonzero__(self): # Python 2 compatibility return self.__bool__() diff --git a/tests/test_serialization.py b/tests/test_serialization.py index b995658d..10dd5505 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -37,4 +37,7 @@ def test_cachefiles(): # remove link to file from spec source generator # test __getstate__ of ImageCacheFile file.generator.source = None - pickleback(file) + restored_file = pickleback(file) + assert file is not restored_file + # Assertion for #437 and #451 + assert file.storage is restored_file.storage From 66db460c244570e353e2dcdf52bd3f47aeb6b1a0 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Tue, 25 Sep 2018 00:37:25 +0300 Subject: [PATCH 445/527] Python 3.6 and Django 2.1 Stop testing some configurations of older Django versions. --- .travis.yml | 82 ++++++++++---------------- tox.ini | 165 ++++++---------------------------------------------- 2 files changed, 50 insertions(+), 197 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4fcb9fcc..b920709c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,66 +1,46 @@ +sudo: false language: python - -sudo: false +python: + - "3.6" + - "3.5" +env: + - DJANGO="master" + - DJANGO="21" + - DJANGO="20" + - DJANGO="111" install: - pip install tox script: - - tox + - tox -e py$(python -c 'import sys;print("".join(map(str, sys.version_info[:2])))')-django${DJANGO} matrix: fast_finish: true + allow_failures: + - env: DJANGO="master" include: - - env: TOXENV=py27-django14 - python: 2.7 - - env: TOXENV=py27-django15 - python: 2.7 - - env: TOXENV=py27-django16 - python: 2.7 - - env: TOXENV=py27-django17 - python: 2.7 - - env: TOXENV=py27-django18 - python: 2.7 - - env: TOXENV=py27-django19 - python: 2.7 - - env: TOXENV=py27-django110 - python: 2.7 - - env: TOXENV=py27-django111 - python: 2.7 - - env: TOXENV=py33-django15 - python: 3.3 - - env: TOXENV=py33-django16 - python: 3.3 - - env: TOXENV=py33-django17 - python: 3.3 - - env: TOXENV=py33-django18 - python: 3.3 - - env: TOXENV=py34-django16 - python: 3.4 - - env: TOXENV=py34-django17 - python: 3.4 - - env: TOXENV=py34-django18 - python: 3.4 - - env: TOXENV=py34-django19 - python: 3.4 - - env: TOXENV=py34-django110 - python: 3.4 - - env: TOXENV=py34-django111 - python: 3.4 - - env: TOXENV=py34-django20 - python: 3.4 - - env: TOXENV=py35-django18 - python: 3.5 - - env: TOXENV=py35-django19 - python: 3.5 - - env: TOXENV=py35-django110 - python: 3.5 - - env: TOXENV=py35-django111 - python: 3.5 - - env: TOXENV=py35-django20 - python: 3.5 + - python: "3.5" + env: DJANGO="18" + - python: "3.4" + env: DJANGO="20" + - python: "3.4" + env: DJANGO="111" + - python: "3.4" + env: DJANGO="18" + - python: "3.4" + env: DJANGO="16" + + - python: "2.7" + env: DJANGO="111" + - python: "2.7" + env: DJANGO="18" + - python: "2.7" + env: DJANGO="16" + - python: "2.7" + env: DJANGO="14" notifications: irc: "irc.freenode.org#imagekit" diff --git a/tox.ini b/tox.ini index 653e3018..86f63c50 100644 --- a/tox.ini +++ b/tox.ini @@ -1,153 +1,26 @@ [tox] envlist = - py35-django20, py35-django111, py35-django110, py35-django19, py35-django18, - py34-django20, py34-django111, py34-django110, py34-django19, py34-django18, py34-django17, py34-django16, - py33-django18, py33-django17, py33-django16, py33-django15, - py27-django111, py27-django110, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, + py36-django{master,21,20,111}, + py35-django{master,21,20,111,18}, + py34-django{21,20,111,18,16}, + py27-django{111,18,16,14} [testenv] commands = python setup.py test -[testenv:py35-django20] -basepython = python3.5 deps = - Django>=2.0,<2.1 - django-nose==1.4.5 - -[testenv:py35-django111] -basepython = python3.5 -deps = - Django>=1.11,<1.12 - django-nose==1.4.5 - -[testenv:py35-django110] -basepython = python3.5 -deps = - Django>=1.10,<1.11 - django-nose==1.4.4 - -[testenv:py35-django19] -basepython = python3.5 -deps = - Django>=1.9,<1.10 - django-nose==1.4.2 - -[testenv:py35-django18] -basepython = python3.5 -deps = - Django>=1.8,<1.9 - django-nose==1.4.2 - -[testenv:py34-django20] -basepython = python3.4 -deps = - Django>=2.0,<2.1 - django-nose==1.4.5 - -[testenv:py34-django111] -basepython = python3.4 -deps = - Django>=1.11,<1.12 - django-nose==1.4.5 - -[testenv:py34-django110] -basepython = python3.4 -deps = - Django>=1.10,<1.11 - django-nose==1.4.4 - -[testenv:py34-django19] -basepython = python3.4 -deps = - Django>=1.9,<1.10 - django-nose==1.4.2 - -[testenv:py34-django18] -basepython = python3.4 -deps = - Django>=1.8,<1.9 - django-nose==1.4.2 - -[testenv:py34-django17] -basepython = python3.4 -deps = - Django>=1.7,<1.8 - django-nose==1.4 - -[testenv:py34-django16] -basepython = python3.4 -deps = - Django>=1.6,<1.7 - django-nose<=1.4.2 - -[testenv:py33-django18] -basepython = python3.3 -deps = - Django>=1.8,<1.9 - django-nose==1.4.2 - -[testenv:py33-django17] -basepython = python3.3 -deps = - Django>=1.7,<1.8 - django-nose==1.4 - -[testenv:py33-django16] -basepython = python3.3 -deps = - Django>=1.6,<1.7 - django-nose<=1.4.2 - -[testenv:py33-django15] -basepython = python3.3 -deps = - Django>=1.5,<1.6 - django-nose==1.4 - -[testenv:py27-django111] -basepython = python2.7 -deps = - Django>=1.11,<1.12 - django-nose==1.4.5 - -[testenv:py27-django110] -basepython = python2.7 -deps = - Django>=1.10,<1.11 - django-nose==1.4.4 - -[testenv:py27-django19] -basepython = python2.7 -deps = - Django>=1.9,<1.10 - django-nose==1.4.2 - -[testenv:py27-django18] -basepython = python2.7 -deps = - Django>=1.8,<1.9 - django-nose==1.4.2 - -[testenv:py27-django17] -basepython = python2.7 -deps = - Django>=1.7,<1.8 - django-nose==1.4 - -[testenv:py27-django16] -basepython = python2.7 -deps = - Django>=1.6,<1.7 - django-nose<=1.4.2 - -[testenv:py27-django15] -basepython = python2.7 -deps = - Django>=1.5,<1.6 - django-nose==1.4 - -[testenv:py27-django14] -basepython = python2.7 -deps = - Django>=1.4,<1.5 - django-nose==1.4 + djangomaster: git+https://github.com/django/django.git@master#egg=Django + django21: Django>=2.1,<2.2 + django20: Django>=2.0,<2.1 + django111: Django>=1.11,<2.0 + django110: Django>=1.10,<1.11 + django19: Django>=1.9,<1.10 + django18: Django>=1.8,<1.9 + django17: Django>=1.7,<1.8 + django16: Django>=1.6,<1.7 + django15: Django>=1.5,<1.6 + django14: Django>=1.4,<1.5 + django{21,20,111}: django-nose==1.4.5 + django110: django-nose==1.4.4 + django{19,18,17,16}: django-nose==1.4.2 + django{15,14}: django-nose==1.4 From 2c85d5aafec7b0d2050eb2af9af9ed5a235135f6 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Fri, 12 Oct 2018 23:05:06 +0300 Subject: [PATCH 446/527] Do not check for existence if name is None This will fix tests for Django master --- imagekit/cachefiles/backends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index e006dc80..2ab4024e 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -110,7 +110,7 @@ def generate(self, file, force=False): def _exists(self, file): return bool(getattr(file, '_file', None) - or file.storage.exists(file.name)) + or (file.name and file.storage.exists(file.name))) def _generate_file(backend, file, force=False): From 60f35b0af5db87c6c0ee361ea707a7773807fc9f Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Fri, 12 Oct 2018 23:08:20 +0300 Subject: [PATCH 447/527] Pass features to BeautifulSoup constructor This will remove a warning durring tests --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 8b16a09a..314daed7 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -64,7 +64,7 @@ def render_tag(ttag): def get_html_attrs(ttag): - return BeautifulSoup(render_tag(ttag)).img.attrs + return BeautifulSoup(render_tag(ttag), features="html.parser").img.attrs def assert_file_is_falsy(file): From 85f0741594dbcf5d74dbee5d1b28c94d333792b1 Mon Sep 17 00:00:00 2001 From: Noah Hall Date: Thu, 20 Feb 2020 22:25:29 -0500 Subject: [PATCH 448/527] fix broken links in documentation (#319) --- README.rst | 1 + docs/caching.rst | 6 +++++- docs/upgrading.rst | 13 +++---------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/README.rst b/README.rst index d797561e..a1fab51b 100644 --- a/README.rst +++ b/README.rst @@ -39,6 +39,7 @@ Installation Usage Overview ============== +.. _specs: Specs ----- diff --git a/docs/caching.rst b/docs/caching.rst index 8264089b..6b576fcc 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -3,7 +3,7 @@ Caching Default Backend Workflow -================ +======================== ``ImageSpec`` @@ -29,6 +29,8 @@ objects, but they've got a little trick up their sleeve: they represent files that may not actually exist! +.. _cache-file-strategy: + Cache File Strategy ------------------- @@ -55,6 +57,8 @@ The default strategy only defines the first two of these, as follows: file.generate() +.. _cache-file-backend: + Cache File Backend ------------------ diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 2a48a75d..15eab6d1 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -79,12 +79,9 @@ IK3 provides analogous settings for cache file backends and strategies: IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'path.to.MyCacheFileBackend' IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = 'path.to.MyCacheFileStrategy' -See the documentation on `cache file backends`_ and `cache file strategies`_ +See the documentation on :ref:`cache file backends ` and :ref:`cache file strategies ` for more details. -.. _`cache file backends`: -.. _`cache file strategies`: - Conditional model ``processors`` -------------------------------- @@ -93,9 +90,7 @@ In IK2, an ``ImageSpecField`` could take a ``processors`` callable instead of an iterable, which allowed processing decisions to made based on other properties of the model. IK3 does away with this feature for consistency's sake (if one kwarg could be callable, why not all?), but provides a much more robust -solution: the custom ``spec``. See the `advanced usage`_ documentation for more. - -.. _`advanced usage`: +solution: the custom ``spec``. See the :doc:`advanced usage ` documentation for more. Conditonal ``cache_to`` file names @@ -109,9 +104,7 @@ There is a way to achieve custom file names by overriding your spec's ``cachefile_name``, but it is not recommended, as the spec's default behavior is to hash the combination of ``source``, ``processors``, ``format``, and other spec options to ensure that changes to the spec always result in -unique file names. See the documentation on `specs`_ for more. - -.. _`specs`: +unique file names. See the documentation on :ref:`specs` for more. Processors have moved to PILKit From 9d450a78b8bafdcbfd4d3e8eb61cf69e18dc18f6 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sun, 8 Mar 2020 13:04:21 +1100 Subject: [PATCH 449/527] docs: Fix simple typo, assigment -> assignment There is a small typo in tests/test_generateimage_tag.py, tests/test_thumbnail_tag.py. Should read `assignment` rather than `assigment`. --- tests/test_generateimage_tag.py | 2 +- tests/test_thumbnail_tag.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index db3f5772..e53c365a 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -30,7 +30,7 @@ def test_dangling_html_attrs_delimiter(): @raises(TemplateSyntaxError) def test_html_attrs_assignment(): """ - You can either use generateimage as an assigment tag or specify html attrs, + You can either use generateimage as an assignment tag or specify html attrs, but not both. """ diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index c9382241..7299ad62 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -42,7 +42,7 @@ def test_too_many_args(): @raises(TemplateSyntaxError) def test_html_attrs_assignment(): """ - You can either use thumbnail as an assigment tag or specify html attrs, + You can either use thumbnail as an assignment tag or specify html attrs, but not both. """ From 9c99503ae4d1f7cbf5ce1119efeda13941c2f4e8 Mon Sep 17 00:00:00 2001 From: Karthikeyan Singaravelan Date: Fri, 17 Apr 2020 14:37:07 +0000 Subject: [PATCH 450/527] Fix deprecation warning regarding invalid escape sequences. --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 35f184d7..c8672a85 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,7 +54,7 @@ # built documents. # # The short X.Y version. -version = re.match('\d+\.\d+', pkgmeta['__version__']).group() +version = re.match(r'\d+\.\d+', pkgmeta['__version__']).group() # The full version, including alpha/beta/rc tags. release = pkgmeta['__version__'] From 1ac11439c201ca9bf9347372d790a4b95526d636 Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Sat, 9 Jan 2021 16:46:06 -0500 Subject: [PATCH 451/527] Use gettext_lazy in Django 2.0+ (ugettext_lazy is deprecated) ugettext is an alias for gettext() since Django 2.0, and deprecated as of Django 3.0. Avoid deprecation warning: > RemovedInDjango40Warning: django.utils.translation.ugettext_lazy() > is deprecated in favor of django.utils.translation.gettext_lazy() Ref: - https://docs.djangoproject.com/en/3.1/releases/3.0/#features-deprecated-in-3-0 - https://github.com/django/django/blob/2b443cb6c2d55669b20019f2755c0711c3d23050/django/utils/translation/__init__.py#L139 --- imagekit/admin.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/imagekit/admin.py b/imagekit/admin.py index 6b37a4c4..9d73d9c0 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -1,4 +1,10 @@ -from django.utils.translation import ugettext_lazy as _ +from django import VERSION +if VERSION[0] < 2: + # ugettext is an alias for gettext() since Django 2.0, + # and deprecated as of Django 3.0. + from django.utils.translation import ugettext_lazy as _ +else: + from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string From cd0bda7ca742f979e832bb3c20492517ab0483b1 Mon Sep 17 00:00:00 2001 From: Viacheslav Riazanov Date: Sat, 13 Feb 2021 13:04:14 +0300 Subject: [PATCH 452/527] Add support of celery 5.* --- imagekit/cachefiles/backends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 2ab4024e..b7ea80b8 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -140,7 +140,7 @@ def schedule_generation(self, file, force=False): try: - from celery import task + from celery import shared_task as task except ImportError: pass else: From 25fb405adddd5184f59dd57ef351b9d0c73ba95d Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Fri, 16 Jul 2021 09:27:57 +0800 Subject: [PATCH 453/527] Accept cachefile_storage that is callable Make it similar to django. Fix #525 --- imagekit/cachefiles/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 08ea04be..30ea755e 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -22,8 +22,8 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c """ :param generator: The object responsible for generating a new image. :param name: The filename - :param storage: A Django storage object that will be used to save the - file. + :param storage: A Django storage object, or a callable which returns a + storage object that will be used to save the file. :param cachefile_backend: The object responsible for managing the state of the file. :param cachefile_strategy: The object responsible for handling events @@ -40,9 +40,9 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c name = fn(generator) self.name = name - storage = storage or getattr(generator, 'cachefile_storage', - None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, - 'file storage backend') + storage = (callable(storage) and storage()) or storage or \ + getattr(generator, 'cachefile_storage', None) or get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') self.cachefile_backend = ( cachefile_backend or getattr(generator, 'cachefile_backend', None) From af0210e892820f632f1c1d26d78e8cbce975b787 Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Sun, 1 Aug 2021 01:59:03 +0300 Subject: [PATCH 454/527] feat: Add Dramatiq backend --- imagekit/cachefiles/backends.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index b7ea80b8..c1d28ae1 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -193,3 +193,27 @@ def __init__(self, *args, **kwargs): def schedule_generation(self, file, force=False): _rq_job.delay(self, file, force=force) + + +try: + from dramatiq import actor +except ImportError: + pass +else: + _dramatiq_actor = actor()(_generate_file) + + +class Dramatiq(BaseAsync): + """ + A backend that uses Dramatiq to generate the images. + """ + def __init__(self, *args, **kwargs): + try: + import dramatiq # noqa + except ImportError: + raise ImproperlyConfigured('You must install django-dramatiq to use' + ' imagekit.cachefiles.backends.Dramatiq.') + super(Dramatiq, self).__init__(*args, **kwargs) + + def schedule_generation(self, file, force=False): + _dramatiq_actor.send(self, file, force=force) From 8776552ce6cc8c20c5ae39538fea02e145b7c5ca Mon Sep 17 00:00:00 2001 From: q0w Date: Mon, 9 Aug 2021 15:26:42 +0300 Subject: [PATCH 455/527] chore: Add 'async_dramatiq' extra, django-dramatiq dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 2af1ad58..d289407c 100644 --- a/setup.py +++ b/setup.py @@ -61,6 +61,7 @@ def exec_file(filepath, globalz=None, localz=None): extras_require={ 'async': ['django-celery>=3.0'], 'async_rq': ['django-rq>=0.6.0'], + 'async_dramatiq': ['django-dramatiq'], }, classifiers=[ 'Development Status :: 5 - Production/Stable', From 64c07492fdda0c536e78b648ce48870f267c8fcd Mon Sep 17 00:00:00 2001 From: q0w Date: Tue, 10 Aug 2021 10:54:37 +0300 Subject: [PATCH 456/527] chore: Set django-dramatiq min version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d289407c..9b8d432e 100644 --- a/setup.py +++ b/setup.py @@ -61,7 +61,7 @@ def exec_file(filepath, globalz=None, localz=None): extras_require={ 'async': ['django-celery>=3.0'], 'async_rq': ['django-rq>=0.6.0'], - 'async_dramatiq': ['django-dramatiq'], + 'async_dramatiq': ['django-dramatiq>=0.4.0'], }, classifiers=[ 'Development Status :: 5 - Production/Stable', From fd90046c1785a2a084e4a45afd1c4d58c60e8668 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 14:37:30 +0200 Subject: [PATCH 457/527] Switch to GitHub Actions --- .github/workflows/python.yml | 29 +++++++++++++++++++++++ .travis.yml | 46 ------------------------------------ 2 files changed, 29 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/python.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 00000000..4e8da5fe --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,29 @@ +name: Python CI + +on: + push: + branches: [ develop ] + pull_request: + branches: [ develop ] + +jobs: + build: + + runs-on: ubuntu-18.04 + strategy: + max-parallel: 4 + matrix: + python-version: [2.7, 3.3, 3.4, 3.5] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + python -m pip install --upgrade pip tox + - name: Run Tests + run: | + tox -e py$(python -c 'import sys;print("{0}{1}".format(*sys.version_info))') diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b920709c..00000000 --- a/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -sudo: false - -language: python -python: - - "3.6" - - "3.5" -env: - - DJANGO="master" - - DJANGO="21" - - DJANGO="20" - - DJANGO="111" - -install: - - pip install tox - -script: - - tox -e py$(python -c 'import sys;print("".join(map(str, sys.version_info[:2])))')-django${DJANGO} - -matrix: - fast_finish: true - allow_failures: - - env: DJANGO="master" - include: - - python: "3.5" - env: DJANGO="18" - - - python: "3.4" - env: DJANGO="20" - - python: "3.4" - env: DJANGO="111" - - python: "3.4" - env: DJANGO="18" - - python: "3.4" - env: DJANGO="16" - - - python: "2.7" - env: DJANGO="111" - - python: "2.7" - env: DJANGO="18" - - python: "2.7" - env: DJANGO="16" - - python: "2.7" - env: DJANGO="14" - -notifications: - irc: "irc.freenode.org#imagekit" From e9d3e60cb45fb281bbee2ff7e1d206eb0c4e2c71 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 14:57:48 +0200 Subject: [PATCH 458/527] Only test on currently supported versions of Python and Django --- .github/workflows/python.yml | 4 ++-- tox.ini | 27 +++++++++------------------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 4e8da5fe..dff162fe 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -9,11 +9,11 @@ on: jobs: build: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: - python-version: [2.7, 3.3, 3.4, 3.5] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index 86f63c50..b2736267 100644 --- a/tox.ini +++ b/tox.ini @@ -1,26 +1,17 @@ [tox] envlist = - py36-django{master,21,20,111}, - py35-django{master,21,20,111,18}, - py34-django{21,20,111,18,16}, - py27-django{111,18,16,14} + py36-django{22,31,32}, + py37-django{22,31,32}, + py38-django{22,31,32,master}, + py39-django{22,31,32,master}, + py310-django{22,31,32,master [testenv] commands = python setup.py test deps = djangomaster: git+https://github.com/django/django.git@master#egg=Django - django21: Django>=2.1,<2.2 - django20: Django>=2.0,<2.1 - django111: Django>=1.11,<2.0 - django110: Django>=1.10,<1.11 - django19: Django>=1.9,<1.10 - django18: Django>=1.8,<1.9 - django17: Django>=1.7,<1.8 - django16: Django>=1.6,<1.7 - django15: Django>=1.5,<1.6 - django14: Django>=1.4,<1.5 - django{21,20,111}: django-nose==1.4.5 - django110: django-nose==1.4.4 - django{19,18,17,16}: django-nose==1.4.2 - django{15,14}: django-nose==1.4 + django22: django~=2.2.0 + django31: django~=3.1.0 + django32: django~=3.2.0 + From cf66aacc277460ffd7ba2a3f0aa25ca13c2803d1 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:04:22 +0200 Subject: [PATCH 459/527] Remove nose-progressive, it doesn't seem to work with recent Python versions --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 9b8d432e..877fe941 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,6 @@ def exec_file(filepath, globalz=None, localz=None): tests_require=[ 'beautifulsoup4>=4.4.0', 'nose>=1.3.6', - 'nose-progressive>=1.5.1', 'django-nose>=1.4', 'Pillow', 'mock>=1.0.1', From 0dfc5262e802ab23e5bfbcf984596a8c4cb8a2ce Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:15:18 +0200 Subject: [PATCH 460/527] Workaround SuspiciousFileOperation --- tests/test_sourcegroups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index c69b11f3..416b964b 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -23,7 +23,7 @@ def test_source_saved_signal(): source_group = ImageFieldSourceGroup(ImageModel, 'image') receiver = make_counting_receiver(source_group) source_saved.connect(receiver) - ImageModel.objects.create(image=File(get_image_file())) + ImageModel.objects.create(image=File(get_image_file(), name='reference.png')) eq_(receiver.count, 1) @@ -51,5 +51,5 @@ def test_abstract_model_signals(): source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') receiver = make_counting_receiver(source_group) source_saved.connect(receiver) - ConcreteImageModel.objects.create(original_image=File(get_image_file())) + ConcreteImageModel.objects.create(original_image=File(get_image_file(), name='reference.png')) eq_(receiver.count, 1) From fafed15ad1230f717b856da2fbab858aa7d42470 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:33:07 +0200 Subject: [PATCH 461/527] Use tox-gh-actions --- .github/workflows/python.yml | 12 ++++++------ tox.ini | 11 +++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index dff162fe..7caa142d 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -21,9 +21,9 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install Dependencies - run: | - python -m pip install --upgrade pip tox - - name: Run Tests - run: | - tox -e py$(python -c 'import sys;print("{0}{1}".format(*sys.version_info))') + + - name: Install dependencies + run: python -m pip install --upgrade pip tox tox-gh-actions + + - name: Run tests + run: tox diff --git a/tox.ini b/tox.ini index b2736267..3f4311a2 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,15 @@ envlist = py37-django{22,31,32}, py38-django{22,31,32,master}, py39-django{22,31,32,master}, - py310-django{22,31,32,master + py310-django{22,31,32,master} + +[gh-actions] +python = + 3.6: py36 + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: py310 [testenv] commands = python setup.py test @@ -14,4 +22,3 @@ deps = django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 - From e9734ee7f55400df15b1aff76c776987131179f7 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:39:30 +0200 Subject: [PATCH 462/527] Django master branch has been renamed to main at some point Install the zip file of this branch, instead of a git checkout and allow tox to fail when testing against the development branch of Django. --- tox.ini | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tox.ini b/tox.ini index 3f4311a2..5ff52831 100644 --- a/tox.ini +++ b/tox.ini @@ -2,9 +2,9 @@ envlist = py36-django{22,31,32}, py37-django{22,31,32}, - py38-django{22,31,32,master}, - py39-django{22,31,32,master}, - py310-django{22,31,32,master} + py38-django{22,31,32,main}, + py39-django{22,31,32,main}, + py310-django{22,31,32,main} [gh-actions] python = @@ -18,7 +18,10 @@ python = commands = python setup.py test deps = - djangomaster: git+https://github.com/django/django.git@master#egg=Django + djangomain: https://github.com/django/django/archive/refs/heads/main.zip django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 + +ignore_outcome = + djangomain: true From 710fd956eb98f38989c6ce4ffee1a377cd30a090 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:39:42 +0200 Subject: [PATCH 463/527] Upgrade pip before installing other dependencies --- .github/workflows/python.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 7caa142d..847d3a9b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -23,7 +23,9 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install dependencies - run: python -m pip install --upgrade pip tox tox-gh-actions + run: | + python -m pip install --upgrade pip + python -m pip install tox tox-gh-actions - name: Run tests run: tox From 1ba46fa2d084c1b0415d633f0bd3caa37e84515c Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 15:43:56 +0200 Subject: [PATCH 464/527] Remove Python 3.10 from the test matrix because nose doesn't work --- .github/workflows/python.yml | 2 +- tox.ini | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 847d3a9b..f22dabbf 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['3.6', '3.7', '3.8', '3.9'] steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index 5ff52831..5c60e758 100644 --- a/tox.ini +++ b/tox.ini @@ -3,8 +3,7 @@ envlist = py36-django{22,31,32}, py37-django{22,31,32}, py38-django{22,31,32,main}, - py39-django{22,31,32,main}, - py310-django{22,31,32,main} + py39-django{22,31,32,main} [gh-actions] python = @@ -12,7 +11,6 @@ python = 3.7: py37 3.8: py38 3.9: py39 - 3.10: py310 [testenv] commands = python setup.py test From 9e270c51779d15278d698ec766f26321a750ac8f Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 19:43:27 +0200 Subject: [PATCH 465/527] Switch from django-nose to pytest-django --- CONTRIBUTING.rst | 4 ++-- MANIFEST.in | 2 ++ pytest.ini | 3 +++ setup.py | 8 ------- test-requirements.txt | 4 ++++ testrunner.py | 22 ----------------- tests/conftest.py | 8 +++++++ tests/imagegenerators.py | 2 +- tests/settings.py | 17 -------------- tests/test_abstract_models.py | 3 +-- tests/test_cachefiles.py | 30 ++++++++++++------------ tests/test_closing_fieldfiles.py | 8 ++++--- tests/test_fields.py | 18 ++++++++------ tests/test_generateimage_tag.py | 25 ++++++++++---------- tests/test_no_extra_queries.py | 5 ++-- tests/test_optimistic_strategy.py | 11 ++++----- tests/test_serialization.py | 3 +++ tests/test_sourcegroups.py | 12 ++++++---- tests/test_thumbnail_tag.py | 39 ++++++++++++++++--------------- tests/utils.py | 5 ++-- tox.ini | 5 ++-- 21 files changed, 108 insertions(+), 126 deletions(-) create mode 100644 pytest.ini create mode 100644 test-requirements.txt delete mode 100644 testrunner.py create mode 100644 tests/conftest.py diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index b9f2de26..d70a2d6b 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -11,7 +11,7 @@ contributions merged as quickly as possible: tests, first install tox, ``pip install tox``, then use ``tox``. This will let you know about any errors or style issues. 4. While we're talking about tests, creating new ones for your code makes it - much easier for us to merge your code quickly. ImageKit uses nose_, so + much easier for us to merge your code quickly. ImageKit uses pytest_, so writing tests is painless. Check out `ours`__ for examples. 5. It's a good idea to do your work in a branch; that way, you can work on more than one contribution at a time without making them interdependent. @@ -20,5 +20,5 @@ contributions merged as quickly as possible: __ http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html __ https://groups.google.com/forum/#!forum/django-imagekit __ irc://irc.freenode.net/imagekit -.. _nose: https://nose.readthedocs.org/en/latest/ +.. _pytest: https://docs.pytest.org/en/latest/ __ https://github.com/matthewwithanm/django-imagekit/tree/develop/tests diff --git a/MANIFEST.in b/MANIFEST.in index b125b907..934606c2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,8 @@ include AUTHORS include LICENSE include README.rst +include pytest.ini +include test-requirements.txt include testrunner.py include setup.cfg include tests/*.py diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..a1c7384f --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +django_find_project = false +DJANGO_SETTINGS_MODULE = tests.settings diff --git a/setup.py b/setup.py index 877fe941..424cbe7d 100644 --- a/setup.py +++ b/setup.py @@ -44,14 +44,6 @@ def exec_file(filepath, globalz=None, localz=None): packages=find_packages(exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']), zip_safe=False, include_package_data=True, - tests_require=[ - 'beautifulsoup4>=4.4.0', - 'nose>=1.3.6', - 'django-nose>=1.4', - 'Pillow', - 'mock>=1.0.1', - ], - test_suite='testrunner.run_tests', install_requires=[ 'django-appconf>=0.5', 'pilkit>=0.2.0', diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..a24db018 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,4 @@ +# Test requirements +beautifulsoup4 +Pillow +pytest-django diff --git a/testrunner.py b/testrunner.py deleted file mode 100644 index 6b41b0fb..00000000 --- a/testrunner.py +++ /dev/null @@ -1,22 +0,0 @@ -# A wrapper for Django's test runner. -# See http://ericholscher.com/blog/2009/jun/29/enable-setuppy-test-your-django-apps/ -# and http://gremu.net/blog/2010/enable-setuppy-test-your-django-apps/ -import os -import sys - -os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' -test_dir = os.path.dirname(__file__) -sys.path.insert(0, test_dir) - -from django.test.utils import get_runner -from django.conf import settings - - -def run_tests(): - cls = get_runner(settings) - runner = cls() - failures = runner.run_tests(['tests']) - # Clean autogenerated junk before exit - from tests.utils import clear_imagekit_test_files - clear_imagekit_test_files() - sys.exit(failures) diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..89b4f7e2 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,8 @@ +import pytest + +from .utils import clear_imagekit_test_files + + +@pytest.fixture(scope='session', autouse=True) +def imagekit_test_files_teardown(request): + request.addfinalizer(clear_imagekit_test_files) diff --git a/tests/imagegenerators.py b/tests/imagegenerators.py index 11e87b37..11ac5552 100644 --- a/tests/imagegenerators.py +++ b/tests/imagegenerators.py @@ -3,7 +3,7 @@ class TestSpec(ImageSpec): - pass + __test__ = False class ResizeTo1PixelSquare(ImageSpec): diff --git a/tests/settings.py b/tests/settings.py index dc3bb3c7..872dacd4 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -28,25 +28,8 @@ 'django.contrib.contenttypes', 'imagekit', 'tests', - 'django_nose', ] -TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' -NOSE_ARGS = [ - '-s', - - # When the tests are run --with-coverage, these args configure coverage - # reporting (requires coverage to be installed). - # Without the --with-coverage flag, they have no effect. - '--cover-tests', - '--cover-html', - '--cover-package=imagekit', - '--cover-html-dir=%s' % os.path.join(BASE_PATH, 'cover') -] - -if os.getenv('TERM'): - NOSE_ARGS.append('--with-progressive') - CACHE_BACKEND = 'locmem://' # Django >= 1.8 diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py index 302fc07e..e16f73ae 100644 --- a/tests/test_abstract_models.py +++ b/tests/test_abstract_models.py @@ -1,9 +1,8 @@ from imagekit.utils import get_nonabstract_descendants -from nose.tools import eq_ from . models import (AbstractImageModel, ConcreteImageModel, ConcreteImageModelSubclass) def test_nonabstract_descendants_generator(): descendants = list(get_nonabstract_descendants(AbstractImageModel)) - eq_(descendants, [ConcreteImageModel, ConcreteImageModelSubclass]) + assert descendants == [ConcreteImageModel, ConcreteImageModelSubclass] diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index ad01dda3..c627fe33 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,10 +1,11 @@ -import mock +import pytest + +from unittest import mock from django.conf import settings from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple from imagekit.lib import force_bytes -from nose.tools import raises, eq_ from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, DummyAsyncCacheFileBackend, get_unique_image_file, @@ -42,11 +43,11 @@ def test_async_backend_falsiness(): assert_file_is_falsy(file) -@raises(TestSpec.MissingSource) def test_no_source_error(): - spec = TestSpec(source=None) - file = ImageCacheFile(spec) - file.generate() + with pytest.raises(TestSpec.MissingSource): + spec = TestSpec(source=None) + file = ImageCacheFile(spec) + file.generate() def test_repr_does_not_send_existence_required(): @@ -71,7 +72,7 @@ def test_repr_does_not_send_existence_required(): cachefile_backend=DummyAsyncCacheFileBackend() ) file.__repr__() - eq_(signal.send.called, False) + assert signal.send.called is False def test_memcached_cache_key(): @@ -91,25 +92,24 @@ def __init__(self, name): length = 199 - extra_char_count filename = '1' * length file = MockFile(filename) - eq_(backend.get_key(file), '%s%s-state' % - (settings.IMAGEKIT_CACHE_PREFIX, file.name)) + assert backend.get_key(file) == '%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) length = 200 - extra_char_count filename = '1' * length file = MockFile(filename) - eq_(backend.get_key(file), '%s%s:%s' % ( + assert backend.get_key(file) == '%s%s:%s' % ( settings.IMAGEKIT_CACHE_PREFIX, '1' * (200 - len(':') - 32 - len(settings.IMAGEKIT_CACHE_PREFIX)), - md5(force_bytes('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename))).hexdigest())) + md5(force_bytes('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename))).hexdigest()) def test_lazyfile_stringification(): file = LazyImageCacheFile('testspec', source=None) - eq_(str(file), '') - eq_(repr(file), '') + assert str(file) == '' + assert repr(file) == '' source_file = get_image_file() file = LazyImageCacheFile('testspec', source=source_file) file.name = 'a.jpg' - eq_(str(file), 'a.jpg') - eq_(repr(file), '') + assert str(file) == 'a.jpg' + assert repr(file) == '' diff --git a/tests/test_closing_fieldfiles.py b/tests/test_closing_fieldfiles.py index d8693c39..cb8d4e2b 100644 --- a/tests/test_closing_fieldfiles.py +++ b/tests/test_closing_fieldfiles.py @@ -1,9 +1,10 @@ -from nose.tools import assert_false, assert_true +import pytest from .models import Thumbnail from .utils import create_photo +@pytest.mark.django_db(transaction=True) def test_do_not_leak_open_files(): instance = create_photo('leak-test.jpg') source_file = instance.original_image @@ -11,9 +12,10 @@ def test_do_not_leak_open_files(): source_file.close() image_generator = Thumbnail(source=source_file) image_generator.generate() - assert_true(source_file.closed) + assert source_file.closed +@pytest.mark.django_db(transaction=True) def test_do_not_close_open_files_after_generate(): instance = create_photo('do-not-close-test.jpg') source_file = instance.original_image @@ -21,5 +23,5 @@ def test_do_not_close_open_files_after_generate(): source_file.open() image_generator = Thumbnail(source=source_file) image_generator.generate() - assert_false(source_file.closed) + assert not source_file.closed source_file.close() diff --git a/tests/test_fields.py b/tests/test_fields.py index 96e73379..f243d101 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1,9 +1,10 @@ +import pytest + from django import forms from django.core.files.base import File from django.core.files.uploadedfile import SimpleUploadedFile from imagekit import forms as ikforms from imagekit.processors import SmartCrop -from nose.tools import eq_ from . import imagegenerators # noqa from .models import (ProcessedImageFieldModel, ProcessedImageFieldWithSpecModel, @@ -11,26 +12,29 @@ from .utils import get_image_file +@pytest.mark.django_db(transaction=True) def test_model_processedimagefield(): instance = ProcessedImageFieldModel() file = File(get_image_file()) instance.processed.save('whatever.jpeg', file) instance.save() - eq_(instance.processed.width, 50) - eq_(instance.processed.height, 50) + assert instance.processed.width == 50 + assert instance.processed.height == 50 +@pytest.mark.django_db(transaction=True) def test_model_processedimagefield_with_spec(): instance = ProcessedImageFieldWithSpecModel() file = File(get_image_file()) instance.processed.save('whatever.jpeg', file) instance.save() - eq_(instance.processed.width, 100) - eq_(instance.processed.height, 60) + assert instance.processed.width == 100 + assert instance.processed.height == 60 +@pytest.mark.django_db(transaction=True) def test_form_processedimagefield(): class TestForm(forms.ModelForm): image = ikforms.ProcessedImageField(spec_id='tests:testform_image', @@ -45,5 +49,5 @@ class Meta: form = TestForm({}, file_dict) instance = form.save() - eq_(instance.image.width, 50) - eq_(instance.image.height, 50) + assert instance.image.width == 50 + assert instance.image.height == 50 diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index e53c365a..879f4c31 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,5 +1,6 @@ +import pytest + from django.template import TemplateSyntaxError -from nose.tools import eq_, assert_false, raises, assert_not_equal from . import imagegenerators # noqa from .utils import render_tag, get_html_attrs, clear_imagekit_cache @@ -9,33 +10,33 @@ def test_img_tag(): clear_imagekit_cache() attrs = get_html_attrs(ttag) expected_attrs = set(['src', 'width', 'height']) - eq_(set(attrs.keys()), expected_attrs) + assert set(attrs.keys()) == expected_attrs for k in expected_attrs: - assert_not_equal(attrs[k].strip(), '') + assert attrs[k].strip() != '' def test_img_tag_attrs(): ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - eq_(attrs.get('alt'), 'Hello') + assert attrs.get('alt') == 'Hello' -@raises(TemplateSyntaxError) def test_dangling_html_attrs_delimiter(): - ttag = r"""{% generateimage 'testspec' source=img -- %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% generateimage 'testspec' source=img -- %}""" + render_tag(ttag) -@raises(TemplateSyntaxError) def test_html_attrs_assignment(): """ You can either use generateimage as an assignment tag or specify html attrs, but not both. """ - ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" as th %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" as th %}""" + render_tag(ttag) def test_single_dimension_attr(): @@ -46,11 +47,11 @@ def test_single_dimension_attr(): ttag = r"""{% generateimage 'testspec' source=img -- width="50" %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - assert_false('height' in attrs) + assert not 'height' in attrs def test_assignment_tag(): ttag = r"""{% generateimage 'testspec' source=img as th %}{{ th.url }}{{ th.height }}{{ th.width }}""" clear_imagekit_cache() html = render_tag(ttag) - assert_not_equal(html.strip(), '') + assert html.strip() != '' diff --git a/tests/test_no_extra_queries.py b/tests/test_no_extra_queries.py index 89c68cb4..6445051e 100644 --- a/tests/test_no_extra_queries.py +++ b/tests/test_no_extra_queries.py @@ -1,5 +1,4 @@ -from nose.tools import assert_false -from mock import Mock, PropertyMock, patch +from unittest.mock import Mock, PropertyMock, patch from .models import Photo @@ -13,4 +12,4 @@ def test_dont_access_source(): pmock.__get__ = Mock() with patch.object(Photo, 'original_image', pmock): photo = Photo() # noqa - assert_false(pmock.__get__.called) + assert not pmock.__get__.called diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index 18b8f3fd..26389db0 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -1,6 +1,5 @@ -from nose.tools import assert_true, assert_false from imagekit.cachefiles import ImageCacheFile -from mock import Mock +from unittest.mock import Mock from .utils import create_image from django.core.files.storage import FileSystemStorage from imagekit.cachefiles.backends import Simple as SimpleCFBackend @@ -33,8 +32,8 @@ def test_no_io_on_bool(): """ file = get_image_cache_file() bool(file) - assert_false(file.storage.exists.called) - assert_false(file.storage.open.called) + assert not file.storage.exists.called + assert not file.storage.open.called def test_no_io_on_url(): @@ -45,5 +44,5 @@ def test_no_io_on_url(): """ file = get_image_cache_file() file.url - assert_false(file.storage.exists.called) - assert_false(file.storage.open.called) + assert not file.storage.exists.called + assert not file.storage.open.called diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 10dd5505..08cbc77a 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -3,12 +3,14 @@ deserialized. This is important when using IK with Celery. """ +import pytest from imagekit.cachefiles import ImageCacheFile from .imagegenerators import TestSpec from .utils import create_photo, pickleback, get_unique_image_file, clear_imagekit_cache +@pytest.mark.django_db(transaction=True) def test_imagespecfield(): clear_imagekit_cache() instance = create_photo('pickletest2.jpg') @@ -16,6 +18,7 @@ def test_imagespecfield(): thumbnail.generate() +@pytest.mark.django_db(transaction=True) def test_circular_ref(): """ A model instance with a spec field in its dict shouldn't raise a KeyError. diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index 416b964b..317715a1 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -1,7 +1,8 @@ +import pytest + from django.core.files import File from imagekit.signals import source_saved from imagekit.specs.sourcegroups import ImageFieldSourceGroup -from nose.tools import eq_ from . models import AbstractImageModel, ImageModel, ConcreteImageModel from .utils import get_image_file @@ -14,6 +15,7 @@ def receiver(sender, *args, **kwargs): return receiver +@pytest.mark.django_db(transaction=True) def test_source_saved_signal(): """ Creating a new instance with an image causes the source_saved signal to be @@ -24,9 +26,10 @@ def test_source_saved_signal(): receiver = make_counting_receiver(source_group) source_saved.connect(receiver) ImageModel.objects.create(image=File(get_image_file(), name='reference.png')) - eq_(receiver.count, 1) + assert receiver.count == 1 +@pytest.mark.django_db(transaction=True) def test_no_source_saved_signal(): """ Creating a new instance without an image shouldn't cause the source_saved @@ -39,9 +42,10 @@ def test_no_source_saved_signal(): receiver = make_counting_receiver(source_group) source_saved.connect(receiver) ImageModel.objects.create() - eq_(receiver.count, 0) + assert receiver.count == 0 +@pytest.mark.django_db(transaction=True) def test_abstract_model_signals(): """ Source groups created for abstract models must cause signals to be @@ -52,4 +56,4 @@ def test_abstract_model_signals(): receiver = make_counting_receiver(source_group) source_saved.connect(receiver) ConcreteImageModel.objects.create(original_image=File(get_image_file(), name='reference.png')) - eq_(receiver.count, 1) + assert receiver.count == 1 diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 7299ad62..0ee940fd 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,5 +1,6 @@ +import pytest + from django.template import TemplateSyntaxError -from nose.tools import eq_, raises, assert_not_equal from . import imagegenerators # noqa from .utils import render_tag, get_html_attrs, clear_imagekit_cache @@ -9,63 +10,63 @@ def test_img_tag(): clear_imagekit_cache() attrs = get_html_attrs(ttag) expected_attrs = set(['src', 'width', 'height']) - eq_(set(attrs.keys()), expected_attrs) + assert set(attrs.keys()) == expected_attrs for k in expected_attrs: - assert_not_equal(attrs[k].strip(), '') + assert attrs[k].strip() != '' def test_img_tag_attrs(): ttag = r"""{% thumbnail '100x100' img -- alt="Hello" %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - eq_(attrs.get('alt'), 'Hello') + assert attrs.get('alt') == 'Hello' -@raises(TemplateSyntaxError) def test_dangling_html_attrs_delimiter(): - ttag = r"""{% thumbnail '100x100' img -- %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% thumbnail '100x100' img -- %}""" + render_tag(ttag) -@raises(TemplateSyntaxError) def test_not_enough_args(): - ttag = r"""{% thumbnail '100x100' %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% thumbnail '100x100' %}""" + render_tag(ttag) -@raises(TemplateSyntaxError) def test_too_many_args(): - ttag = r"""{% thumbnail 'generator_id' '100x100' img 'extra' %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% thumbnail 'generator_id' '100x100' img 'extra' %}""" + render_tag(ttag) -@raises(TemplateSyntaxError) def test_html_attrs_assignment(): """ You can either use thumbnail as an assignment tag or specify html attrs, but not both. """ - ttag = r"""{% thumbnail '100x100' img -- alt="Hello" as th %}""" - render_tag(ttag) + with pytest.raises(TemplateSyntaxError): + ttag = r"""{% thumbnail '100x100' img -- alt="Hello" as th %}""" + render_tag(ttag) def test_assignment_tag(): ttag = r"""{% thumbnail '100x100' img as th %}{{ th.url }}""" clear_imagekit_cache() html = render_tag(ttag) - assert_not_equal(html, '') + assert html != '' def test_single_dimension(): ttag = r"""{% thumbnail '100x' img as th %}{{ th.width }}""" clear_imagekit_cache() html = render_tag(ttag) - eq_(html, '100') + assert html == '100' def test_alternate_generator(): ttag = r"""{% thumbnail '1pxsq' '100x' img as th %}{{ th.width }}""" clear_imagekit_cache() html = render_tag(ttag) - eq_(html, '1') + assert html == '1' diff --git a/tests/utils.py b/tests/utils.py index 314daed7..61ce882b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -7,7 +7,6 @@ from imagekit.conf import settings from imagekit.lib import Image, StringIO from imagekit.utils import get_cache -from nose.tools import assert_true, assert_false import pickle from tempfile import NamedTemporaryFile from .models import Photo @@ -68,11 +67,11 @@ def get_html_attrs(ttag): def assert_file_is_falsy(file): - assert_false(bool(file), 'File is not falsy') + assert not bool(file), 'File is not falsy' def assert_file_is_truthy(file): - assert_true(bool(file), 'File is not truthy') + assert bool(file), 'File is not truthy' class DummyAsyncCacheFileBackend(Simple): diff --git a/tox.ini b/tox.ini index 5c60e758..e2249198 100644 --- a/tox.ini +++ b/tox.ini @@ -13,13 +13,14 @@ python = 3.9: py39 [testenv] -commands = python setup.py test - deps = + -r test-requirements.txt djangomain: https://github.com/django/django/archive/refs/heads/main.zip django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 +commands = python -m pytest + ignore_outcome = djangomain: true From 2669d2b250f083fad98485ee5c1a3b0d30ed89f0 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 13 Oct 2021 19:43:53 +0200 Subject: [PATCH 466/527] Add Python 3.10 to the test matrix --- .github/workflows/python.yml | 2 +- tox.ini | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index f22dabbf..847d3a9b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.6', '3.7', '3.8', '3.9'] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index e2249198..f24bb608 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,7 @@ [tox] envlist = - py36-django{22,31,32}, - py37-django{22,31,32}, - py38-django{22,31,32,main}, - py39-django{22,31,32,main} + py{36,37,38,39,310}-django{22,31,32}, + py310-djangomain [gh-actions] python = @@ -11,14 +9,15 @@ python = 3.7: py37 3.8: py38 3.9: py39 + 3.10: py310 [testenv] deps = -r test-requirements.txt - djangomain: https://github.com/django/django/archive/refs/heads/main.zip django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 + djangomain: https://github.com/django/django/archive/refs/heads/main.zip commands = python -m pytest From 86703a5450ae6bad2d5e1fd905db61ca09b1947d Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:01:54 +0200 Subject: [PATCH 467/527] Add coverage reporting --- .coveragerc | 9 +++++++++ test-requirements.txt | 2 ++ tox.ini | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..33d71ab8 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,9 @@ +[run] +branch = true +parallel = true + +[report] +show_missing = true +skip_empty = true +skip_covered = true +precision = 2 diff --git a/test-requirements.txt b/test-requirements.txt index a24db018..9a7d3abb 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,6 @@ # Test requirements beautifulsoup4 Pillow +pytest +pytest-cov pytest-django diff --git a/tox.ini b/tox.ini index f24bb608..62502a5c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,8 @@ [tox] envlist = py{36,37,38,39,310}-django{22,31,32}, - py310-djangomain + py310-djangomain, + coverage-report [gh-actions] python = @@ -19,7 +20,16 @@ deps = django32: django~=3.2.0 djangomain: https://github.com/django/django/archive/refs/heads/main.zip -commands = python -m pytest +setenv = COVERAGE_FILE=.coverage.{envname} +commands = python -m pytest --cov --cov-report term-missing:skip-covered ignore_outcome = djangomain: true + +[testenv:coverage-report] +deps = coverage +skip_install = true +setenv = COVERAGE_FILE=.coverage +commands = + coverage combine + coverage report From 0932442ae93899130ca5216552a5a8f86ea1797b Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:08:07 +0200 Subject: [PATCH 468/527] Minor improvements to the tests --- tests/test_cachefiles.py | 4 ++-- tests/test_generateimage_tag.py | 6 +++--- tests/test_thumbnail_tag.py | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index c627fe33..51a8e299 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -44,9 +44,9 @@ def test_async_backend_falsiness(): def test_no_source_error(): + spec = TestSpec(source=None) + file = ImageCacheFile(spec) with pytest.raises(TestSpec.MissingSource): - spec = TestSpec(source=None) - file = ImageCacheFile(spec) file.generate() diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 879f4c31..4ab795d9 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -23,8 +23,8 @@ def test_img_tag_attrs(): def test_dangling_html_attrs_delimiter(): + ttag = r"""{% generateimage 'testspec' source=img -- %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% generateimage 'testspec' source=img -- %}""" render_tag(ttag) @@ -34,8 +34,8 @@ def test_html_attrs_assignment(): but not both. """ + ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" as th %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" as th %}""" render_tag(ttag) @@ -47,7 +47,7 @@ def test_single_dimension_attr(): ttag = r"""{% generateimage 'testspec' source=img -- width="50" %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - assert not 'height' in attrs + assert 'height' not in attrs def test_assignment_tag(): diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 0ee940fd..31a0116e 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -23,20 +23,20 @@ def test_img_tag_attrs(): def test_dangling_html_attrs_delimiter(): + ttag = r"""{% thumbnail '100x100' img -- %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% thumbnail '100x100' img -- %}""" render_tag(ttag) def test_not_enough_args(): + ttag = r"""{% thumbnail '100x100' %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% thumbnail '100x100' %}""" render_tag(ttag) def test_too_many_args(): + ttag = r"""{% thumbnail 'generator_id' '100x100' img 'extra' %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% thumbnail 'generator_id' '100x100' img 'extra' %}""" render_tag(ttag) @@ -46,8 +46,8 @@ def test_html_attrs_assignment(): but not both. """ + ttag = r"""{% thumbnail '100x100' img -- alt="Hello" as th %}""" with pytest.raises(TemplateSyntaxError): - ttag = r"""{% thumbnail '100x100' img -- alt="Hello" as th %}""" render_tag(ttag) From 420567409ad86d33bca1f6c9d72785b9eaea05f6 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:47:54 +0200 Subject: [PATCH 469/527] Use GitHub actions workflow badge --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a1fab51b..78f5916a 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ |Build Status|_ -.. |Build Status| image:: https://travis-ci.org/matthewwithanm/django-imagekit.svg?branch=develop -.. _Build Status: https://travis-ci.org/matthewwithanm/django-imagekit +.. |Build Status| image:: https://github.com/matthewwithanm/django-imagekit/actions/workflows/python.yml/badge.svg?branch=develop +.. _Build Status: https://github.com/matthewwithanm/django-imagekit/actions/workflows/python.yml ImageKit is a Django app for processing images. Need a thumbnail? A black-and-white version of a user-uploaded image? ImageKit will make them for From 013343c07a629e6dd50242bbfcff38633f00cf42 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:48:42 +0200 Subject: [PATCH 470/527] Fix spelling / rst errors --- README.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 78f5916a..7286e482 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ ImageKit is a Django app for processing images. Need a thumbnail? A black-and-white version of a user-uploaded image? ImageKit will make them for -you. If you need to programatically generate one image from another, you need +you. If you need to programmatically generate one image from another, you need ImageKit. ImageKit comes with a bunch of image processors for common tasks like resizing @@ -447,7 +447,7 @@ AdminThumbnail can even use a custom template. For more information, see Management Commands ------------------- -ImageKit has one management command—`generateimages`—which will generate cache +ImageKit has one management command—``generateimages``—which will generate cache files for all of your registered image generators. You can also pass it a list of generator ids in order to generate images selectively. @@ -473,9 +473,8 @@ people, open a pull request so we can take a look! You can also check out our list of `open, contributor-friendly issues`__ for ideas. -Check out our `contributing guidelines`__ for more information about pitching in +Check out our `contributing guidelines`_ for more information about pitching in with ImageKit. - __ https://github.com/matthewwithanm/django-imagekit/issues?labels=contributor-friendly&state=open -__ https://github.com/matthewwithanm/django-imagekit/blob/develop/CONTRIBUTING.rst +.. _`contributing guidelines`: https://github.com/matthewwithanm/django-imagekit/blob/develop/CONTRIBUTING.rst From 8ea152d53d21770d6c1f5685daeb6b3b3ea190fa Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:49:29 +0200 Subject: [PATCH 471/527] Remove PIL from the installation instructions --- README.rst | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index 7286e482..e82f10e4 100644 --- a/README.rst +++ b/README.rst @@ -22,17 +22,11 @@ __ https://github.com/fish2000/instakit Installation ============ -1. Install `PIL`_ or `Pillow`_. (If you're using an ``ImageField`` in Django, +1. Install `Pillow`_. (If you're using an ``ImageField`` in Django, you should have already done this.) 2. ``pip install django-imagekit`` -3. Add ``'imagekit'`` to your ``INSTALLED_APPS`` list in your project's settings.py +3. Add ``'imagekit'`` to your ``INSTALLED_APPS`` list in your project's ``settings.py`` -.. note:: If you've never seen Pillow before, it considers itself a - more-frequently updated "friendly" fork of PIL that's compatible with - setuptools. As such, it shares the same namespace as PIL does and is a - drop-in replacement. - -.. _`PIL`: http://pypi.python.org/pypi/PIL .. _`Pillow`: http://pypi.python.org/pypi/Pillow From 2d911f5689d537c46061e0b0dc50b1d464ca204a Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:49:52 +0200 Subject: [PATCH 472/527] Add more Python versions to the classifiers --- setup.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup.py b/setup.py index 877fe941..0fbc7c4d 100644 --- a/setup.py +++ b/setup.py @@ -75,6 +75,11 @@ def exec_file(filepath, globalz=None, localz=None): 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Utilities' ], ) From 088d60db95c6ec637802209b7c2502f0c1106ac6 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 11:50:58 +0200 Subject: [PATCH 473/527] Add myself to the list of contributors --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 6f4c2380..5438b944 100644 --- a/AUTHORS +++ b/AUTHORS @@ -29,6 +29,7 @@ Contributors * `Sean Bell`_ * `Saul Shanabrook`_ * `Venelin Stoykov`_ +* `Jaap Roes`_ .. _Justin Driscoll: http://github.com/jdriscoll .. _HZDG: http://hzdg.com @@ -51,3 +52,4 @@ Contributors .. _Sean Bell: https://github.com/seanbell .. _Saul Shanabrook: https://github.com/saulshanabrook .. _Venelin Stoykov: https://github.com/vstoykov +.. Jaap Roes: https://github.com/jaap3 From 07f66b86d931e873a45e4ba908d4356fbe2cc8dc Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 12:53:08 +0200 Subject: [PATCH 474/527] Run coverage-report (combined coverage) on Python 3.10 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 62502a5c..4e075c1c 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ python = 3.7: py37 3.8: py38 3.9: py39 - 3.10: py310 + 3.10: py310, coverage-report [testenv] deps = From 3c4f0a3ca3094510253b273042720e4fefd39e07 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 22 Sep 2021 10:05:56 +0200 Subject: [PATCH 475/527] Import force/smart_str instead of force/smart_text force_text and smart_text were deprecated in Django 3.0 and are removed in Django 4.0 --- imagekit/lib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index 5a4240b8..e858f90f 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -40,7 +40,9 @@ def emit(self, record): # If Django version is under 1.5 then use `force_unicde` # It is used for compatibility between Python 2 and Python 3 try: - from django.utils.encoding import force_text, force_bytes, smart_text + from django.utils.encoding import (force_str as force_text, + force_bytes, + smart_str as smart_text) except ImportError: # Django < 1.5 from django.utils.encoding import (force_unicode as force_text, From 6dd0a9a6f34fad6f6a591b4aa61656bd0ecca400 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Tue, 19 Oct 2021 10:16:27 +0200 Subject: [PATCH 476/527] Ensure Python 2.7 compatibility --- .github/workflows/python.yml | 2 +- setup.py | 3 ++- test-requirements.txt | 1 + tests/test_cachefiles.py | 6 +++++- tests/test_no_extra_queries.py | 6 +++++- tests/test_optimistic_strategy.py | 7 ++++++- tox.ini | 3 +++ 7 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 847d3a9b..05e22765 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['2.7', '3.6', '3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index ef62fd45..c018b750 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,8 @@ def exec_file(filepath, globalz=None, localz=None): zip_safe=False, include_package_data=True, install_requires=[ - 'django-appconf>=0.5', + "django-appconf>=0.5,<1.0.4; python_version<'3'", + "django-appconf; python_version>'3'", 'pilkit>=0.2.0', 'six', ], diff --git a/test-requirements.txt b/test-requirements.txt index 9a7d3abb..a8c7120a 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,5 @@ # Test requirements +mock; python_version<'3' beautifulsoup4 Pillow pytest diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 51a8e299..7e6b622e 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,6 +1,10 @@ import pytest -from unittest import mock +try: + from unittest import mock +except ImportError: + import mock + from django.conf import settings from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile diff --git a/tests/test_no_extra_queries.py b/tests/test_no_extra_queries.py index 6445051e..0a2dffb7 100644 --- a/tests/test_no_extra_queries.py +++ b/tests/test_no_extra_queries.py @@ -1,4 +1,8 @@ -from unittest.mock import Mock, PropertyMock, patch +try: + from unittest.mock import Mock, PropertyMock, patch +except: + from mock import Mock, PropertyMock, patch + from .models import Photo diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index 26389db0..04407da6 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -1,5 +1,10 @@ from imagekit.cachefiles import ImageCacheFile -from unittest.mock import Mock + +try: + from unittest.mock import Mock +except: + from mock import Mock + from .utils import create_image from django.core.files.storage import FileSystemStorage from imagekit.cachefiles.backends import Simple as SimpleCFBackend diff --git a/tox.ini b/tox.ini index 4e075c1c..382a3561 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,13 @@ [tox] envlist = + py27-django111 py{36,37,38,39,310}-django{22,31,32}, py310-djangomain, coverage-report [gh-actions] python = + 2.7: py27 3.6: py36 3.7: py37 3.8: py38 @@ -15,6 +17,7 @@ python = [testenv] deps = -r test-requirements.txt + django111: django~=1.11.0 django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 From 3bb1c3b6c16145cd9f5cbd253e39d5707999190f Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Tue, 2 Nov 2021 08:25:58 +0200 Subject: [PATCH 477/527] Fix python 2 compatibility --- imagekit/lib.py | 22 +++++++++++++--------- tox.ini | 3 ++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index e858f90f..bdc51c13 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,4 +1,5 @@ # flake8: noqa +import sys # Required PIL classes may or may not be available from the root namespace # depending on the installation method used. @@ -39,15 +40,18 @@ def emit(self, record): # This function will replace `unicode` used in the code # If Django version is under 1.5 then use `force_unicde` # It is used for compatibility between Python 2 and Python 3 -try: - from django.utils.encoding import (force_str as force_text, - force_bytes, - smart_str as smart_text) -except ImportError: - # Django < 1.5 - from django.utils.encoding import (force_unicode as force_text, - smart_str as force_bytes, - smart_unicode as smart_text) +if sys.version_info >= (3, 0): + from django.utils.encoding import (force_bytes, + force_str as force_text, + smart_str as smart_text) +else: + try: + from django.utils.encoding import force_text, force_bytes, smart_text + except ImportError: + # Django < 1.5 + from django.utils.encoding import (force_unicode as force_text, + smart_str as force_bytes, + smart_unicode as smart_text) __all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', diff --git a/tox.ini b/tox.ini index 382a3561..f71b83cc 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py27-django111 + py27-django{111,18} py{36,37,38,39,310}-django{22,31,32}, py310-djangomain, coverage-report @@ -17,6 +17,7 @@ python = [testenv] deps = -r test-requirements.txt + django18: django~=1.8.0 django111: django~=1.11.0 django22: django~=2.2.0 django31: django~=3.1.0 From 7da461cfb25fc6006a5b21c4e8b6b0d97d3cb6e5 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Tue, 2 Nov 2021 08:38:14 +0200 Subject: [PATCH 478/527] Bump version to 4.1.0 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index afdaca40..4745e7bd 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '4.0.2' +__version__ = '4.1.0' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 60f35e7596566fac7f736210bd276be8a5a036db Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 11:10:22 +0100 Subject: [PATCH 479/527] Only test on currently supported versions of Python and Django --- .github/workflows/python.yml | 2 +- tox.ini | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 05e22765..847d3a9b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['2.7', '3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index f71b83cc..4e075c1c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,11 @@ [tox] envlist = - py27-django{111,18} py{36,37,38,39,310}-django{22,31,32}, py310-djangomain, coverage-report [gh-actions] python = - 2.7: py27 3.6: py36 3.7: py37 3.8: py38 @@ -17,8 +15,6 @@ python = [testenv] deps = -r test-requirements.txt - django18: django~=1.8.0 - django111: django~=1.11.0 django22: django~=2.2.0 django31: django~=3.1.0 django32: django~=3.2.0 From d7d44bdec13f32146dd95c746c572c70e4c31e43 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 16:07:53 +0200 Subject: [PATCH 480/527] Remove fallback settings --- tests/settings.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/settings.py b/tests/settings.py index 872dacd4..ed59d4bc 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -8,12 +8,6 @@ MEDIA_ROOT = os.path.normpath(os.path.join(BASE_PATH, 'media')) -# Django <= 1.2 -DATABASE_ENGINE = 'sqlite3' -DATABASE_NAME = 'imagekit.db' -TEST_DATABASE_NAME = 'imagekit-test.db' - -# Django >= 1.3 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', @@ -32,7 +26,6 @@ CACHE_BACKEND = 'locmem://' -# Django >= 1.8 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', From 155025d2dfbdc86df40f7923127b9049ae2df424 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 14:44:29 +0200 Subject: [PATCH 481/527] Remove fallback imports --- imagekit/admin.py | 8 +----- imagekit/hashers.py | 11 +++----- imagekit/lib.py | 62 ++++++--------------------------------------- imagekit/utils.py | 17 +++---------- 4 files changed, 15 insertions(+), 83 deletions(-) diff --git a/imagekit/admin.py b/imagekit/admin.py index 9d73d9c0..9861fd1e 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -1,10 +1,4 @@ -from django import VERSION -if VERSION[0] < 2: - # ugettext is an alias for gettext() since Django 2.0, - # and deprecated as of Django 3.0. - from django.utils.translation import ugettext_lazy as _ -else: - from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string diff --git a/imagekit/hashers.py b/imagekit/hashers.py index 12825bda..9b9de6e9 100644 --- a/imagekit/hashers.py +++ b/imagekit/hashers.py @@ -1,12 +1,7 @@ from copy import copy from hashlib import md5 -from pickle import MARK, DICT -try: - from pickle import _Pickler -except ImportError: - # Python 2 compatible - from pickle import Pickler as _Pickler -from .lib import StringIO +from io import BytesIO +from pickle import DICT, MARK, _Pickler class CanonicalizingPickler(_Pickler): @@ -30,6 +25,6 @@ def save_dict(self, obj): def pickle(obj): - file = StringIO() + file = BytesIO() CanonicalizingPickler(file, 0).dump(obj) return md5(file.getvalue()).hexdigest() diff --git a/imagekit/lib.py b/imagekit/lib.py index bdc51c13..62b1223e 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,57 +1,11 @@ -# flake8: noqa -import sys - -# Required PIL classes may or may not be available from the root namespace -# depending on the installation method used. -try: - from PIL import Image, ImageColor, ImageChops, ImageEnhance, ImageFile, \ - ImageFilter, ImageDraw, ImageStat -except ImportError: - try: - import Image - import ImageColor - import ImageChops - import ImageEnhance - import ImageFile - import ImageFilter - import ImageDraw - import ImageStat - except ImportError: - raise ImportError('ImageKit was unable to import the Python Imaging Library. Please confirm it`s installed and available on your current Python path.') - -try: - from io import BytesIO as StringIO -except: - try: - from cStringIO import StringIO - except ImportError: - from StringIO import StringIO - -try: - from logging import NullHandler -except ImportError: - from logging import Handler - - class NullHandler(Handler): - def emit(self, record): - pass - -# Try to import `force_text` available from Django 1.5 -# This function will replace `unicode` used in the code -# If Django version is under 1.5 then use `force_unicde` -# It is used for compatibility between Python 2 and Python 3 -if sys.version_info >= (3, 0): - from django.utils.encoding import (force_bytes, - force_str as force_text, - smart_str as smart_text) -else: - try: - from django.utils.encoding import force_text, force_bytes, smart_text - except ImportError: - # Django < 1.5 - from django.utils.encoding import (force_unicode as force_text, - smart_str as force_bytes, - smart_unicode as smart_text) +from io import BytesIO as StringIO +from logging import NullHandler + +from django.utils.encoding import force_bytes +from django.utils.encoding import force_str as force_text +from django.utils.encoding import smart_str as smart_text +from PIL import (Image, ImageChops, ImageColor, ImageDraw, ImageEnhance, + ImageFile, ImageFilter, ImageStat) __all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', diff --git a/imagekit/utils.py b/imagekit/utils.py index ca6727ae..87a9d0c6 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -3,14 +3,11 @@ import re from tempfile import NamedTemporaryFile from hashlib import md5 +from importlib import import_module from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files import File -try: - from importlib import import_module -except ImportError: - from django.utils.importlib import import_module from pilkit.utils import * from .lib import NullHandler, force_bytes @@ -93,10 +90,7 @@ def _autodiscover_modules_fallback(): Used for Django versions < 1.7 """ from django.conf import settings - try: - from importlib import import_module - except ImportError: - from django.utils.importlib import import_module + from importlib import import_module from django.utils.module_loading import module_has_submodule for app in settings.INSTALLED_APPS: @@ -167,12 +161,7 @@ def call_strategy_method(file, method_name): def get_cache(): - try: - from django.core.cache import caches - except ImportError: - # Django < 1.7 - from django.core.cache import get_cache - return get_cache(settings.IMAGEKIT_CACHE_BACKEND) + from django.core.cache import caches return caches[settings.IMAGEKIT_CACHE_BACKEND] From 6f9b388dd31de86ba9140132905cdadc2b2ce7bb Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 14:45:07 +0200 Subject: [PATCH 482/527] Remove __future__ imports --- imagekit/files.py | 1 - imagekit/models/fields/__init__.py | 2 -- imagekit/templatetags/imagekit.py | 2 -- imagekit/utils.py | 1 - 4 files changed, 6 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index f64cf697..ba9c8ccc 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals import os from django.core.files.base import File, ContentFile diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 767374f2..d1793ab0 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.conf import settings from django.db import models from django.db.models.signals import class_prepared diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 5a69c915..77a5eac2 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django import template from django.utils.html import escape from django.utils.safestring import mark_safe diff --git a/imagekit/utils.py b/imagekit/utils.py index 87a9d0c6..be886b30 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,4 +1,3 @@ -from __future__ import unicode_literals import logging import re from tempfile import NamedTemporaryFile From c47d476b3eddef8d43ce484f22c9f66978b45eb0 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 16:01:45 +0200 Subject: [PATCH 483/527] Remove compatibility with South --- imagekit/models/fields/__init__.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index d1793ab0..a48a0709 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -112,13 +112,3 @@ def __init__(self, processors=None, format=None, options=None, def contribute_to_class(self, cls, name): self._set_spec_id(cls, name) return super(ProcessedImageField, self).contribute_to_class(cls, name) - - -# If the project does not use south, then we will not try to add introspection -if 'south' in settings.INSTALLED_APPS: - try: - from south.modelsinspector import add_introspection_rules - except ImportError: - pass - else: - add_introspection_rules([], [r'^imagekit\.models\.fields\.ProcessedImageField$']) From df1ff52214ab04a60121c25fb643cbabb5a3763b Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 14:57:09 +0200 Subject: [PATCH 484/527] Remove lib.smart_text / lib.force_text / lib.force_bytes --- imagekit/cachefiles/strategies.py | 1 - imagekit/files.py | 7 +------ imagekit/lib.py | 6 +----- imagekit/templatetags/imagekit.py | 6 +++--- imagekit/utils.py | 4 ++-- tests/test_cachefiles.py | 3 +-- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index bcd8211e..118df2d5 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -1,7 +1,6 @@ import six from django.utils.functional import LazyObject -from ..lib import force_text from ..utils import get_singleton diff --git a/imagekit/files.py b/imagekit/files.py index ba9c8ccc..8a98732b 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,7 +2,6 @@ from django.core.files.base import File, ContentFile from django.utils.encoding import smart_str -from .lib import smart_text from .utils import format_to_mimetype, extension_to_mimetype @@ -102,8 +101,4 @@ def name(self): return self.file.name def __str__(self): - return smart_str(self.file.name or '') - - def __unicode__(self): - # Python 2 - return smart_text(self.file.name or '') + return str(self.file.name or '') diff --git a/imagekit/lib.py b/imagekit/lib.py index 62b1223e..fee67447 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,12 +1,8 @@ from io import BytesIO as StringIO from logging import NullHandler -from django.utils.encoding import force_bytes -from django.utils.encoding import force_str as force_text -from django.utils.encoding import smart_str as smart_text from PIL import (Image, ImageChops, ImageColor, ImageDraw, ImageEnhance, ImageFile, ImageFilter, ImageStat) __all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', - 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', - 'force_text', 'force_bytes', 'smart_text'] + 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler'] diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 77a5eac2..92ebbbca 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,11 +1,11 @@ from django import template +from django.utils.encoding import force_str from django.utils.html import escape from django.utils.safestring import mark_safe from ..compat import parse_bits from ..cachefiles import ImageCacheFile from ..registry import generator_registry -from ..lib import force_text register = template.Library() @@ -42,7 +42,7 @@ def __init__(self, variable_name, generator_id, generator_kwargs): self._variable_name = variable_name def get_variable_name(self, context): - return force_text(self._variable_name) + return force_str(self._variable_name) def render(self, context): variable_name = self.get_variable_name(context) @@ -85,7 +85,7 @@ def __init__(self, variable_name, generator_id, dimensions, source, generator_kw self._generator_kwargs = generator_kwargs def get_variable_name(self, context): - return force_text(self._variable_name) + return force_str(self._variable_name) def render(self, context): variable_name = self.get_variable_name(context) diff --git a/imagekit/utils.py b/imagekit/utils.py index be886b30..ca21e166 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -8,7 +8,7 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files import File from pilkit.utils import * -from .lib import NullHandler, force_bytes +from .lib import NullHandler bad_memcached_key_chars = re.compile('[\u0000-\u001f\\s]+') @@ -173,7 +173,7 @@ def sanitize_cache_key(key): # The also can't be > 250 chars long. Since we don't know what the # user's cache ``KEY_FUNCTION`` setting is like, we'll limit it to 200. if len(new_key) >= 200: - new_key = '%s:%s' % (new_key[:200-33], md5(force_bytes(key)).hexdigest()) + new_key = '%s:%s' % (new_key[:200-33], md5(key.encode('utf-8')).hexdigest()) key = new_key return key diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 7e6b622e..28edddc0 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -9,7 +9,6 @@ from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple -from imagekit.lib import force_bytes from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, DummyAsyncCacheFileBackend, get_unique_image_file, @@ -104,7 +103,7 @@ def __init__(self, name): assert backend.get_key(file) == '%s%s:%s' % ( settings.IMAGEKIT_CACHE_PREFIX, '1' * (200 - len(':') - 32 - len(settings.IMAGEKIT_CACHE_PREFIX)), - md5(force_bytes('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename))).hexdigest()) + md5(('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename)).encode('utf-8')).hexdigest()) def test_lazyfile_stringification(): From 61e0817fa99503f09a6ba55896fb5f0e3e5f9d6c Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 14:58:32 +0200 Subject: [PATCH 485/527] Remove lib.NullHandler in favor of using logging.NullHandler directly --- imagekit/lib.py | 3 +-- imagekit/utils.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index fee67447..7b39ca7f 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,8 +1,7 @@ from io import BytesIO as StringIO -from logging import NullHandler from PIL import (Image, ImageChops, ImageColor, ImageDraw, ImageEnhance, ImageFile, ImageFilter, ImageStat) __all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', - 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler'] + 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO'] diff --git a/imagekit/utils.py b/imagekit/utils.py index ca21e166..267c7c1c 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -8,7 +8,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files import File from pilkit.utils import * -from .lib import NullHandler bad_memcached_key_chars = re.compile('[\u0000-\u001f\\s]+') @@ -113,7 +112,7 @@ def _autodiscover_modules_fallback(): def get_logger(logger_name='imagekit', add_null_handler=True): logger = logging.getLogger(logger_name) if add_null_handler: - logger.addHandler(NullHandler()) + logger.addHandler(logging.NullHandler()) return logger From 4f2bcff7455ac91e1315c9dc9d1203dd2054d3e7 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 15:07:43 +0200 Subject: [PATCH 486/527] Remove lib.StringIO --- imagekit/lib.py | 4 +--- tests/utils.py | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index 7b39ca7f..e3e4392c 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -1,7 +1,5 @@ -from io import BytesIO as StringIO - from PIL import (Image, ImageChops, ImageColor, ImageDraw, ImageEnhance, ImageFile, ImageFilter, ImageStat) __all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', - 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO'] + 'ImageFilter', 'ImageDraw', 'ImageStat'] diff --git a/tests/utils.py b/tests/utils.py index 61ce882b..62e8247b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,11 +1,12 @@ from bs4 import BeautifulSoup import os import shutil +from io import BytesIO from django.core.files import File from django.template import Context, Template from imagekit.cachefiles.backends import Simple, CacheFileState from imagekit.conf import settings -from imagekit.lib import Image, StringIO +from imagekit.lib import Image from imagekit.utils import get_cache import pickle from tempfile import NamedTemporaryFile @@ -49,7 +50,7 @@ def create_photo(name): def pickleback(obj): - pickled = StringIO() + pickled = BytesIO() pickle.dump(obj, pickled) pickled.seek(0) return pickle.load(pickled) From 6a90247dfd7d968bb8158c0ccebc3f132227bc39 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 15:08:57 +0200 Subject: [PATCH 487/527] Remove lib module --- imagekit/lib.py | 5 ----- tests/utils.py | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 imagekit/lib.py diff --git a/imagekit/lib.py b/imagekit/lib.py deleted file mode 100644 index e3e4392c..00000000 --- a/imagekit/lib.py +++ /dev/null @@ -1,5 +0,0 @@ -from PIL import (Image, ImageChops, ImageColor, ImageDraw, ImageEnhance, - ImageFile, ImageFilter, ImageStat) - -__all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', - 'ImageFilter', 'ImageDraw', 'ImageStat'] diff --git a/tests/utils.py b/tests/utils.py index 62e8247b..bce49e98 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,8 +6,8 @@ from django.template import Context, Template from imagekit.cachefiles.backends import Simple, CacheFileState from imagekit.conf import settings -from imagekit.lib import Image from imagekit.utils import get_cache +from PIL import Image import pickle from tempfile import NamedTemporaryFile from .models import Photo From dbbfa45ab0fb9d6b7ca8bdf5b5838f28d43e1633 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 15:04:40 +0200 Subject: [PATCH 488/527] Remove usage of six --- imagekit/cachefiles/strategies.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index 118df2d5..eb7c54f7 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -1,5 +1,3 @@ -import six - from django.utils.functional import LazyObject from ..utils import get_singleton @@ -39,7 +37,7 @@ def __init__(self, callbacks): def load_strategy(strategy): - if isinstance(strategy, six.string_types): + if isinstance(strategy, str): strategy = get_singleton(strategy, 'cache file strategy') elif isinstance(strategy, dict): strategy = DictStrategy(strategy) From 2c34e4c0b19566b6113c2ed9e66d771cc9b5e51b Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 15:38:38 +0200 Subject: [PATCH 489/527] Use the parse_bits implementation from Django --- imagekit/compat.py | 161 ------------------------------ imagekit/templatetags/imagekit.py | 8 +- 2 files changed, 4 insertions(+), 165 deletions(-) delete mode 100644 imagekit/compat.py diff --git a/imagekit/compat.py b/imagekit/compat.py deleted file mode 100644 index f26e8b87..00000000 --- a/imagekit/compat.py +++ /dev/null @@ -1,161 +0,0 @@ -# flake8: noqa -""" -This module contains code from django.template.base -(sha 90d3af380e8efec0301dd91600c6686232de3943). Bundling this code allows us to -support older versions of Django that did not contain it (< 1.4). - - -Copyright (c) Django Software Foundation and individual contributors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of Django nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -""" - -from django.template import TemplateSyntaxError -import re - - -# Regex for token keyword arguments -kwarg_re = re.compile(r"(?:(\w+)=)?(.+)") - - -def token_kwargs(bits, parser, support_legacy=False): - """ - A utility method for parsing token keyword arguments. - - :param bits: A list containing remainder of the token (split by spaces) - that is to be checked for arguments. Valid arguments will be removed - from this list. - - :param support_legacy: If set to true ``True``, the legacy format - ``1 as foo`` will be accepted. Otherwise, only the standard ``foo=1`` - format is allowed. - - :returns: A dictionary of the arguments retrieved from the ``bits`` token - list. - - There is no requirement for all remaining token ``bits`` to be keyword - arguments, so the dictionary will be returned as soon as an invalid - argument format is reached. - """ - if not bits: - return {} - match = kwarg_re.match(bits[0]) - kwarg_format = match and match.group(1) - if not kwarg_format: - if not support_legacy: - return {} - if len(bits) < 3 or bits[1] != 'as': - return {} - - kwargs = {} - while bits: - if kwarg_format: - match = kwarg_re.match(bits[0]) - if not match or not match.group(1): - return kwargs - key, value = match.groups() - del bits[:1] - else: - if len(bits) < 3 or bits[1] != 'as': - return kwargs - key, value = bits[2], bits[0] - del bits[:3] - kwargs[key] = parser.compile_filter(value) - if bits and not kwarg_format: - if bits[0] != 'and': - return kwargs - del bits[:1] - return kwargs - - -def parse_bits(parser, bits, params, varargs, varkw, defaults, - takes_context, name): - """ - Parses bits for template tag helpers (simple_tag, include_tag and - assignment_tag), in particular by detecting syntax errors and by - extracting positional and keyword arguments. - """ - if takes_context: - if params[0] == 'context': - params = params[1:] - else: - raise TemplateSyntaxError( - "'%s' is decorated with takes_context=True so it must " - "have a first argument of 'context'" % name) - args = [] - kwargs = {} - unhandled_params = list(params) - for bit in bits: - # First we try to extract a potential kwarg from the bit - kwarg = token_kwargs([bit], parser) - if kwarg: - # The kwarg was successfully extracted - param, value = list(kwarg.items())[0] - if param not in params and varkw is None: - # An unexpected keyword argument was supplied - raise TemplateSyntaxError( - "'%s' received unexpected keyword argument '%s'" % - (name, param)) - elif param in kwargs: - # The keyword argument has already been supplied once - raise TemplateSyntaxError( - "'%s' received multiple values for keyword argument '%s'" % - (name, param)) - else: - # All good, record the keyword argument - kwargs[str(param)] = value - if param in unhandled_params: - # If using the keyword syntax for a positional arg, then - # consume it. - unhandled_params.remove(param) - else: - if kwargs: - raise TemplateSyntaxError( - "'%s' received some positional argument(s) after some " - "keyword argument(s)" % name) - else: - # Record the positional argument - args.append(parser.compile_filter(bit)) - try: - # Consume from the list of expected positional arguments - unhandled_params.pop(0) - except IndexError: - if varargs is None: - raise TemplateSyntaxError( - "'%s' received too many positional arguments" % - name) - if defaults is not None: - # Consider the last n params handled, where n is the - # number of defaults. - unhandled_params = unhandled_params[:-len(defaults)] - if unhandled_params: - # Some positional arguments were not supplied - raise TemplateSyntaxError( - "'%s' did not receive value(s) for the argument(s): %s" % - (name, ", ".join(["'%s'" % p for p in unhandled_params]))) - return args, kwargs diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 92ebbbca..9bfde7e4 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,9 +1,9 @@ from django import template +from django.template.library import parse_bits from django.utils.encoding import force_str from django.utils.html import escape from django.utils.safestring import mark_safe -from ..compat import parse_bits from ..cachefiles import ImageCacheFile from ..registry import generator_registry @@ -167,7 +167,7 @@ def parse_ik_tag_bits(parser, bits): ' setting html attributes.' % HTML_ATTRS_DELIMITER) args, html_attrs = parse_bits(parser, html_bits, [], 'args', - 'kwargs', None, False, tag_name) + 'kwargs', None, [], None, False, tag_name) if len(args): raise template.TemplateSyntaxError('All "%s" tag arguments after' ' the "%s" token must be named.' % (tag_name, @@ -209,7 +209,7 @@ def generateimage(parser, token): tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) args, kwargs = parse_bits(parser, bits, ['generator_id'], 'args', 'kwargs', - None, False, tag_name) + None, [], None, False, tag_name) if len(args) != 1: raise template.TemplateSyntaxError('The "%s" tag requires exactly one' @@ -257,7 +257,7 @@ def thumbnail(parser, token): tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) args, kwargs = parse_bits(parser, bits, [], 'args', 'kwargs', - None, False, tag_name) + None, [], None, False, tag_name) if len(args) < 2: raise template.TemplateSyntaxError('The "%s" tag requires at least two' From eaa8f1da82ac71985ebc2858622ebf0841099401 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 16:04:48 +0200 Subject: [PATCH 490/527] Remove _autodiscover_modules_fallback --- imagekit/utils.py | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 267c7c1c..bdb7b3a9 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -67,48 +67,11 @@ def autodiscover(): if _autodiscovered: return - try: - from django.utils.module_loading import autodiscover_modules - except ImportError: - # Django<1.7 - _autodiscover_modules_fallback() - else: - autodiscover_modules('imagegenerators') + from django.utils.module_loading import autodiscover_modules + autodiscover_modules('imagegenerators') _autodiscovered = True -def _autodiscover_modules_fallback(): - """ - Auto-discover INSTALLED_APPS imagegenerators.py modules and fail silently - when not present. This forces an import on them to register any admin bits - they may want. - - Copied from django.contrib.admin - - Used for Django versions < 1.7 - """ - from django.conf import settings - from importlib import import_module - from django.utils.module_loading import module_has_submodule - - for app in settings.INSTALLED_APPS: - # As of Django 1.7, settings.INSTALLED_APPS may contain classes instead of modules, hence the try/except - # See here: https://docs.djangoproject.com/en/dev/releases/1.7/#introspecting-applications - try: - mod = import_module(app) - # Attempt to import the app's admin module. - try: - import_module('%s.imagegenerators' % app) - except: - # Decide whether to bubble up this error. If the app just - # doesn't have an imagegenerators module, we can ignore the error - # attempting to import it, otherwise we want it to bubble up. - if module_has_submodule(mod, 'imagegenerators'): - raise - except ImportError: - pass - - def get_logger(logger_name='imagekit', add_null_handler=True): logger = logging.getLogger(logger_name) if add_null_handler: From 9a82563d28b9201e534e9180fb4df17dc53fc935 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 12:25:07 +0100 Subject: [PATCH 491/527] Remove Python 2 compat method --- imagekit/cachefiles/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 30ea755e..1d8720cb 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -162,10 +162,6 @@ def __setstate__(self, state): ) self.__dict__.update(state) - def __nonzero__(self): - # Python 2 compatibility - return self.__bool__() - def __repr__(self): return smart_str("<%s: %s>" % ( self.__class__.__name__, self if self.name else "None") From 719225a139e2697a60123b84d881d54b03721da8 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 16:33:43 +0200 Subject: [PATCH 492/527] Use @register.tag decorator --- imagekit/templatetags/imagekit.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 9bfde7e4..5e4af604 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -176,7 +176,7 @@ def parse_ik_tag_bits(parser, bits): return (tag_name, bits, html_attrs, varname) -#@register.tag +@register.tag def generateimage(parser, token): """ Creates an image based on the provided arguments. @@ -223,7 +223,7 @@ def generateimage(parser, token): return GenerateImageTagNode(generator_id, kwargs, html_attrs) -#@register.tag +@register.tag def thumbnail(parser, token): """ A convenient shortcut syntax for generating a thumbnail. The following:: @@ -277,7 +277,3 @@ def thumbnail(parser, token): else: return ThumbnailImageTagNode(generator_id, dimensions, source, kwargs, html_attrs) - - -generateimage = register.tag(generateimage) -thumbnail = register.tag(thumbnail) From ff9699c3fd547e66129dd737a68a1d720284b780 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 11:58:37 +0100 Subject: [PATCH 493/527] Clean up imports --- docs/_themes/flask_theme_support.py | 5 +++-- docs/conf.py | 4 +++- imagekit/__init__.py | 11 +++++++---- imagekit/admin.py | 2 +- imagekit/cachefiles/__init__.py | 6 ++++-- imagekit/cachefiles/backends.py | 6 ++++-- imagekit/cachefiles/namers.py | 4 +++- imagekit/cachefiles/strategies.py | 1 - imagekit/files.py | 6 +++--- imagekit/forms/fields.py | 1 + imagekit/generatorlibrary.py | 2 +- imagekit/management/commands/generateimages.py | 6 ++++-- imagekit/models/fields/__init__.py | 8 ++++---- imagekit/models/fields/files.py | 6 ++++-- imagekit/signals.py | 1 - imagekit/specs/__init__.py | 6 ++++-- imagekit/specs/sourcegroups.py | 4 +++- imagekit/templatetags/imagekit.py | 1 - imagekit/utils.py | 2 -- setup.py | 2 +- tests/models.py | 3 +-- tests/test_abstract_models.py | 5 +++-- tests/test_cachefiles.py | 18 ++++++++---------- tests/test_fields.py | 8 ++++---- tests/test_generateimage_tag.py | 4 ++-- tests/test_no_extra_queries.py | 5 +---- tests/test_optimistic_strategy.py | 12 +++++------- tests/test_serialization.py | 4 +++- tests/test_sourcegroups.py | 5 +++-- tests/test_thumbnail_tag.py | 4 ++-- tests/utils.py | 13 ++++++++----- 31 files changed, 90 insertions(+), 75 deletions(-) diff --git a/docs/_themes/flask_theme_support.py b/docs/_themes/flask_theme_support.py index 33f47449..436c5685 100755 --- a/docs/_themes/flask_theme_support.py +++ b/docs/_themes/flask_theme_support.py @@ -1,7 +1,8 @@ # flasky extensions. flasky pygments style based on tango style from pygments.style import Style -from pygments.token import Keyword, Name, Comment, String, Error, \ - Number, Operator, Generic, Whitespace, Punctuation, Other, Literal +from pygments.token import (Comment, Error, Generic, Keyword, Literal, Name, + Number, Operator, Other, Punctuation, String, + Whitespace) class FlaskyStyle(Style): diff --git a/docs/conf.py b/docs/conf.py index c8672a85..3e0009dd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import re, sys, os +import os +import re +import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 6e92fb34..1f0ffc4a 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,6 +1,9 @@ -# flake8: noqa -from . import conf -from . import generatorlibrary -from .specs import ImageSpec +from . import conf, generatorlibrary from .pkgmeta import * from .registry import register, unregister +from .specs import ImageSpec + +__all__ = [ + 'ImageSpec', 'conf', 'generatorlibrary', 'register', 'unregister', + '__title__', '__author__', '__version__', '__license__' +] diff --git a/imagekit/admin.py b/imagekit/admin.py index 9861fd1e..6a0c5b45 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -1,5 +1,5 @@ -from django.utils.translation import gettext_lazy as _ from django.template.loader import render_to_string +from django.utils.translation import gettext_lazy as _ class AdminThumbnail(object): diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 1d8720cb..b76de728 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -1,13 +1,15 @@ from copy import copy + from django.conf import settings from django.core.files import File from django.core.files.images import ImageFile -from django.utils.functional import SimpleLazyObject from django.utils.encoding import smart_str +from django.utils.functional import SimpleLazyObject + from ..files import BaseIKFile from ..registry import generator_registry from ..signals import content_required, existence_required -from ..utils import get_logger, get_singleton, generate, get_by_qname +from ..utils import generate, get_by_qname, get_logger, get_singleton class ImageCacheFile(BaseIKFile, ImageFile): diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index c1d28ae1..95791f87 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -1,8 +1,10 @@ -from ..utils import get_singleton, get_cache, sanitize_cache_key import warnings from copy import copy -from django.core.exceptions import ImproperlyConfigured + from django.conf import settings +from django.core.exceptions import ImproperlyConfigured + +from ..utils import get_cache, get_singleton, sanitize_cache_key class CacheFileState(object): diff --git a/imagekit/cachefiles/namers.py b/imagekit/cachefiles/namers.py index d6bc95a3..52469402 100644 --- a/imagekit/cachefiles/namers.py +++ b/imagekit/cachefiles/namers.py @@ -5,8 +5,10 @@ """ -from django.conf import settings import os + +from django.conf import settings + from ..utils import format_to_extension, suggest_extension diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index eb7c54f7..b9f96216 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -1,4 +1,3 @@ -from django.utils.functional import LazyObject from ..utils import get_singleton diff --git a/imagekit/files.py b/imagekit/files.py index 8a98732b..f317c5e3 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,8 +1,8 @@ import os -from django.core.files.base import File, ContentFile -from django.utils.encoding import smart_str -from .utils import format_to_mimetype, extension_to_mimetype +from django.core.files.base import ContentFile, File + +from .utils import extension_to_mimetype, format_to_mimetype class BaseIKFile(File): diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index cf3ccba6..2adc1972 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -1,4 +1,5 @@ from django.forms import ImageField + from ..specs import SpecHost from ..utils import generate diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index f07e606d..bfae89d9 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -1,5 +1,5 @@ -from .registry import register from .processors import Thumbnail as ThumbnailProcessor +from .registry import register from .specs import ImageSpec diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 2addfd31..e6e63982 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -1,7 +1,9 @@ -from django.core.management.base import BaseCommand import re -from ...registry import generator_registry, cachefile_registry + +from django.core.management.base import BaseCommand + from ...exceptions import MissingSource +from ...registry import cachefile_registry, generator_registry class Command(BaseCommand): diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index a48a0709..80c8250c 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,11 +1,11 @@ -from django.conf import settings from django.db import models from django.db.models.signals import class_prepared -from .files import ProcessedImageFieldFile -from .utils import ImageSpecFileDescriptor + +from ...registry import register from ...specs import SpecHost from ...specs.sourcegroups import ImageFieldSourceGroup -from ...registry import register +from .files import ProcessedImageFieldFile +from .utils import ImageSpecFileDescriptor class SpecHostField(SpecHost): diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 0fbbad63..72c46c11 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,6 +1,8 @@ -from django.db.models.fields.files import ImageFieldFile import os -from ...utils import suggest_extension, generate + +from django.db.models.fields.files import ImageFieldFile + +from ...utils import generate, suggest_extension class ProcessedImageFieldFile(ImageFieldFile): diff --git a/imagekit/signals.py b/imagekit/signals.py index 4bca574c..5430748c 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,6 +1,5 @@ from django.dispatch import Signal - # Generated file signals content_required = Signal() existence_required = Signal() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index d9339f37..8f149915 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,12 +1,14 @@ from copy import copy + from django.conf import settings from django.db.models.fields.files import ImageFieldFile + +from .. import hashers from ..cachefiles.backends import get_default_cachefile_backend from ..cachefiles.strategies import load_strategy -from .. import hashers from ..exceptions import AlreadyRegistered, MissingSource -from ..utils import open_image, get_by_qname, process_image from ..registry import generator_registry, register +from ..utils import get_by_qname, open_image, process_image class BaseImageSpec(object): diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 03a33224..fc49646f 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -10,9 +10,11 @@ """ +import inspect + from django.db.models.signals import post_init, post_save from django.utils.functional import wraps -import inspect + from ..cachefiles import LazyImageCacheFile from ..signals import source_saved from ..utils import get_nonabstract_descendants diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 5e4af604..6513a553 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -7,7 +7,6 @@ from ..cachefiles import ImageCacheFile from ..registry import generator_registry - register = template.Library() diff --git a/imagekit/utils.py b/imagekit/utils.py index bdb7b3a9..a28cd0b0 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,6 +1,5 @@ import logging import re -from tempfile import NamedTemporaryFile from hashlib import md5 from importlib import import_module @@ -9,7 +8,6 @@ from django.core.files import File from pilkit.utils import * - bad_memcached_key_chars = re.compile('[\u0000-\u001f\\s]+') _autodiscovered = False diff --git a/setup.py b/setup.py index c018b750..547d35fe 100644 --- a/setup.py +++ b/setup.py @@ -1,9 +1,9 @@ #!/usr/bin/env python import codecs import os -from setuptools import setup, find_packages import sys +from setuptools import find_packages, setup # Workaround for multiprocessing/nose issue. See http://bugs.python.org/msg170215 try: diff --git a/tests/models.py b/tests/models.py index 0f6bd0c4..a91a57ca 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,8 +1,7 @@ from django.db import models from imagekit import ImageSpec -from imagekit.models import ProcessedImageField -from imagekit.models import ImageSpecField +from imagekit.models import ImageSpecField, ProcessedImageField from imagekit.processors import Adjust, ResizeToFill, SmartCrop diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py index e16f73ae..e0f88ca3 100644 --- a/tests/test_abstract_models.py +++ b/tests/test_abstract_models.py @@ -1,6 +1,7 @@ from imagekit.utils import get_nonabstract_descendants -from . models import (AbstractImageModel, ConcreteImageModel, - ConcreteImageModelSubclass) + +from .models import (AbstractImageModel, ConcreteImageModel, + ConcreteImageModelSubclass) def test_nonabstract_descendants_generator(): diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 28edddc0..5f17d7a4 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,18 +1,16 @@ -import pytest - -try: - from unittest import mock -except ImportError: - import mock +from hashlib import md5 +from unittest import mock +import pytest from django.conf import settings -from hashlib import md5 + from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple + from .imagegenerators import TestSpec -from .utils import (assert_file_is_truthy, assert_file_is_falsy, - DummyAsyncCacheFileBackend, get_unique_image_file, - get_image_file) +from .utils import (DummyAsyncCacheFileBackend, assert_file_is_falsy, + assert_file_is_truthy, get_image_file, + get_unique_image_file) def test_no_source_falsiness(): diff --git a/tests/test_fields.py b/tests/test_fields.py index f243d101..d1eef1b8 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1,14 +1,14 @@ import pytest - from django import forms from django.core.files.base import File from django.core.files.uploadedfile import SimpleUploadedFile + from imagekit import forms as ikforms from imagekit.processors import SmartCrop + from . import imagegenerators # noqa -from .models import (ProcessedImageFieldModel, - ProcessedImageFieldWithSpecModel, - ImageModel) +from .models import (ImageModel, ProcessedImageFieldModel, + ProcessedImageFieldWithSpecModel) from .utils import get_image_file diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 4ab795d9..ffcbb306 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,8 +1,8 @@ import pytest - from django.template import TemplateSyntaxError + from . import imagegenerators # noqa -from .utils import render_tag, get_html_attrs, clear_imagekit_cache +from .utils import clear_imagekit_cache, get_html_attrs, render_tag def test_img_tag(): diff --git a/tests/test_no_extra_queries.py b/tests/test_no_extra_queries.py index 0a2dffb7..612d027e 100644 --- a/tests/test_no_extra_queries.py +++ b/tests/test_no_extra_queries.py @@ -1,7 +1,4 @@ -try: - from unittest.mock import Mock, PropertyMock, patch -except: - from mock import Mock, PropertyMock, patch +from unittest.mock import Mock, PropertyMock, patch from .models import Photo diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index 04407da6..b937aa5a 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -1,15 +1,13 @@ -from imagekit.cachefiles import ImageCacheFile - -try: - from unittest.mock import Mock -except: - from mock import Mock +from unittest.mock import Mock -from .utils import create_image from django.core.files.storage import FileSystemStorage + +from imagekit.cachefiles import ImageCacheFile from imagekit.cachefiles.backends import Simple as SimpleCFBackend from imagekit.cachefiles.strategies import Optimistic as OptimisticStrategy +from .utils import create_image + class ImageGenerator(object): def generate(self): diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 08cbc77a..aa2bc120 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -6,8 +6,10 @@ import pytest from imagekit.cachefiles import ImageCacheFile + from .imagegenerators import TestSpec -from .utils import create_photo, pickleback, get_unique_image_file, clear_imagekit_cache +from .utils import (clear_imagekit_cache, create_photo, get_unique_image_file, + pickleback) @pytest.mark.django_db(transaction=True) diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index 317715a1..8e0b52f8 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -1,9 +1,10 @@ import pytest - from django.core.files import File + from imagekit.signals import source_saved from imagekit.specs.sourcegroups import ImageFieldSourceGroup -from . models import AbstractImageModel, ImageModel, ConcreteImageModel + +from .models import AbstractImageModel, ConcreteImageModel, ImageModel from .utils import get_image_file diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 31a0116e..c1cf0ea6 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,8 +1,8 @@ import pytest - from django.template import TemplateSyntaxError + from . import imagegenerators # noqa -from .utils import render_tag, get_html_attrs, clear_imagekit_cache +from .utils import clear_imagekit_cache, get_html_attrs, render_tag def test_img_tag(): diff --git a/tests/utils.py b/tests/utils.py index bce49e98..0e91ecca 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,15 +1,18 @@ -from bs4 import BeautifulSoup import os +import pickle import shutil from io import BytesIO +from tempfile import NamedTemporaryFile + +from bs4 import BeautifulSoup from django.core.files import File from django.template import Context, Template -from imagekit.cachefiles.backends import Simple, CacheFileState +from PIL import Image + +from imagekit.cachefiles.backends import Simple from imagekit.conf import settings from imagekit.utils import get_cache -from PIL import Image -import pickle -from tempfile import NamedTemporaryFile + from .models import Photo From 34a24d0ed283bf557551789dd8ba3bdabbbb0227 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 17:01:15 +0200 Subject: [PATCH 494/527] Use Python 3 style classes and super calls --- imagekit/admin.py | 2 +- imagekit/cachefiles/__init__.py | 4 ++-- imagekit/cachefiles/backends.py | 14 +++++++------- imagekit/cachefiles/strategies.py | 6 +++--- imagekit/forms/fields.py | 4 ++-- imagekit/generatorlibrary.py | 2 +- imagekit/models/fields/__init__.py | 4 ++-- imagekit/models/fields/files.py | 2 +- imagekit/models/fields/utils.py | 2 +- imagekit/registry.py | 10 +++++----- imagekit/specs/__init__.py | 6 +++--- imagekit/specs/sourcegroups.py | 6 +++--- tests/imagegenerators.py | 2 +- tests/models.py | 2 +- tests/test_cachefiles.py | 2 +- tests/test_optimistic_strategy.py | 2 +- 16 files changed, 35 insertions(+), 35 deletions(-) diff --git a/imagekit/admin.py b/imagekit/admin.py index 6a0c5b45..9e171a97 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -2,7 +2,7 @@ from django.utils.translation import gettext_lazy as _ -class AdminThumbnail(object): +class AdminThumbnail: """ A convenience utility for adding thumbnails to Django's admin change list. diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index b76de728..00643d3d 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -57,7 +57,7 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c 'cache file strategy') ) - super(ImageCacheFile, self).__init__(storage=storage) + super().__init__(storage=storage) def _require_file(self): if getattr(self, '_file', None) is None: @@ -175,7 +175,7 @@ def __init__(self, generator_id, *args, **kwargs): def setup(): generator = generator_registry.get(generator_id, *args, **kwargs) return ImageCacheFile(generator) - super(LazyImageCacheFile, self).__init__(setup) + super().__init__(setup) def __repr__(self): return '<%s: %s>' % (self.__class__.__name__, str(self) or 'None') diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 95791f87..e8423d32 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -7,7 +7,7 @@ from ..utils import get_cache, get_singleton, sanitize_cache_key -class CacheFileState(object): +class CacheFileState: EXISTS = 'exists' GENERATING = 'generating' DOES_NOT_EXIST = 'does_not_exist' @@ -27,7 +27,7 @@ class InvalidFileBackendError(ImproperlyConfigured): pass -class AbstractCacheFileBackend(object): +class AbstractCacheFileBackend: """ An abstract cache file backend. This isn't used by any internal classes and is included simply to illustrate the minimum interface of a cache file @@ -41,7 +41,7 @@ def exists(self, file): raise NotImplementedError -class CachedFileBackend(object): +class CachedFileBackend: existence_check_timeout = 5 """ The number of seconds to wait before rechecking to see if the file exists. @@ -159,7 +159,7 @@ def __init__(self, *args, **kwargs): except ImportError: raise ImproperlyConfigured('You must install celery to use' ' imagekit.cachefiles.backends.Celery.') - super(Celery, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def schedule_generation(self, file, force=False): _celery_task.delay(self, file, force=force) @@ -170,7 +170,7 @@ class Async(Celery): def __init__(self, *args, **kwargs): message = '{path}.Async is deprecated. Use {path}.Celery instead.' warnings.warn(message.format(path=__name__), DeprecationWarning) - super(Async, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) try: @@ -191,7 +191,7 @@ def __init__(self, *args, **kwargs): except ImportError: raise ImproperlyConfigured('You must install django-rq to use' ' imagekit.cachefiles.backends.RQ.') - super(RQ, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def schedule_generation(self, file, force=False): _rq_job.delay(self, file, force=force) @@ -215,7 +215,7 @@ def __init__(self, *args, **kwargs): except ImportError: raise ImproperlyConfigured('You must install django-dramatiq to use' ' imagekit.cachefiles.backends.Dramatiq.') - super(Dramatiq, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def schedule_generation(self, file, force=False): _dramatiq_actor.send(self, file, force=force) diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index b9f96216..8af85bdd 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -1,7 +1,7 @@ from ..utils import get_singleton -class JustInTime(object): +class JustInTime: """ A strategy that ensures the file exists right before it's needed. @@ -14,7 +14,7 @@ def on_content_required(self, file): file.generate() -class Optimistic(object): +class Optimistic: """ A strategy that acts immediately when the source file changes and assumes that the cache files will not be removed (i.e. it doesn't ensure the @@ -29,7 +29,7 @@ def should_verify_existence(self, file): return False -class DictStrategy(object): +class DictStrategy: def __init__(self, callbacks): for k, v in callbacks.items(): setattr(self, k, v) diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index 2adc1972..81d42979 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -18,10 +18,10 @@ def __init__(self, processors=None, format=None, options=None, SpecHost.__init__(self, processors=processors, format=format, options=options, autoconvert=autoconvert, spec=spec, spec_id=spec_id) - super(ProcessedImageField, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) def clean(self, data, initial=None): - data = super(ProcessedImageField, self).clean(data, initial) + data = super().clean(data, initial) if data and data != initial: spec = self.get_spec(source=data) diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index bfae89d9..59f71ef6 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -7,7 +7,7 @@ class Thumbnail(ImageSpec): def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, **kwargs): self.processors = [ThumbnailProcessor(width, height, anchor=anchor, crop=crop, upscale=upscale)] - super(Thumbnail, self).__init__(**kwargs) + super().__init__(**kwargs) register.generator('imagekit:thumbnail', Thumbnail) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 80c8250c..0da1427e 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -20,7 +20,7 @@ def _set_spec_id(self, cls, name): # Register the spec with the id. This allows specs to be overridden # later, from outside of the model definition. - super(SpecHostField, self).set_spec_id(spec_id) + super().set_spec_id(spec_id) class ImageSpecField(SpecHostField): @@ -111,4 +111,4 @@ def __init__(self, processors=None, format=None, options=None, def contribute_to_class(self, cls, name): self._set_spec_id(cls, name) - return super(ProcessedImageField, self).contribute_to_class(cls, name) + return super().contribute_to_class(cls, name) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 72c46c11..d208c5f8 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -12,4 +12,4 @@ def save(self, name, content, save=True): ext = suggest_extension(name, spec.format) new_name = '%s%s' % (filename, ext) content = generate(spec) - return super(ProcessedImageFieldFile, self).save(new_name, content, save) + return super().save(new_name, content, save) diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 6cd74a07..90e00321 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,7 +1,7 @@ from ...cachefiles import ImageCacheFile -class ImageSpecFileDescriptor(object): +class ImageSpecFileDescriptor: def __init__(self, field, attname, source_field_name): self.attname = attname self.field = field diff --git a/imagekit/registry.py b/imagekit/registry.py index 685b094c..bcd3d22b 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -3,7 +3,7 @@ from .utils import autodiscover, call_strategy_method -class GeneratorRegistry(object): +class GeneratorRegistry: """ An object for registering generators. This registry provides a convenient way for a distributable app to define default generators @@ -61,7 +61,7 @@ def _receive(self, file, callback): call_strategy_method(file, callback) -class SourceGroupRegistry(object): +class SourceGroupRegistry: """ The source group registry is responsible for listening to source_* signals on source groups, and relaying them to the image generated file strategies @@ -116,7 +116,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): call_strategy_method(file, callback_name) -class CacheFileRegistry(object): +class CacheFileRegistry: """ An object for registering generated files with image generators. The two are associated with each other via a string id. We do this (as opposed to @@ -156,7 +156,7 @@ def get(self, generator_id): yield file -class Register(object): +class Register: """ Register generators and generated files. @@ -179,7 +179,7 @@ def source_group(self, generator_id, source_group): source_group_registry.register(generator_id, source_group) -class Unregister(object): +class Unregister: """ Unregister generators and generated files. diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 8f149915..96c97282 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -11,7 +11,7 @@ from ..utils import get_by_qname, open_image, process_image -class BaseImageSpec(object): +class BaseImageSpec: """ An object that defines how an new image should be generated from a source image. @@ -87,7 +87,7 @@ class ImageSpec(BaseImageSpec): def __init__(self, source): self.source = source - super(ImageSpec, self).__init__() + super().__init__() @property def cachefile_name(self): @@ -195,7 +195,7 @@ def create_spec(class_attrs, state): return instance -class SpecHost(object): +class SpecHost: """ An object that ostensibly has a spec attribute but really delegates to the spec registry. diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index fc49646f..47fb168a 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -40,7 +40,7 @@ def receiver(self, sender, **kwargs): return receiver -class ModelSignalRouter(object): +class ModelSignalRouter: """ Normally, ``ImageFieldSourceGroup`` would be directly responsible for watching for changes on the model field it represents. However, Django does @@ -126,7 +126,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): signal.send(sender=source_group, source=file) -class ImageFieldSourceGroup(object): +class ImageFieldSourceGroup: """ A source group that repesents a particular field across all instances of a model and its subclasses. @@ -149,7 +149,7 @@ def files(self): yield getattr(instance, self.image_field) -class SourceGroupFilesGenerator(object): +class SourceGroupFilesGenerator: """ A Python generator that yields cache file objects for source groups. diff --git a/tests/imagegenerators.py b/tests/imagegenerators.py index 11ac5552..d6edb356 100644 --- a/tests/imagegenerators.py +++ b/tests/imagegenerators.py @@ -9,7 +9,7 @@ class TestSpec(ImageSpec): class ResizeTo1PixelSquare(ImageSpec): def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): self.processors = [ResizeToFill(1, 1)] - super(ResizeTo1PixelSquare, self).__init__(**kwargs) + super().__init__(**kwargs) register.generator('testspec', TestSpec) diff --git a/tests/models.py b/tests/models.py index a91a57ca..f4892cfd 100644 --- a/tests/models.py +++ b/tests/models.py @@ -37,7 +37,7 @@ class ProcessedImageFieldWithSpecModel(models.Model): processed = ProcessedImageField(spec=Thumbnail, upload_to='p') -class CountingCacheFileStrategy(object): +class CountingCacheFileStrategy: def __init__(self): self.on_existence_required_count = 0 self.on_content_required_count = 0 diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 5f17d7a4..f7caf4f7 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -83,7 +83,7 @@ def test_memcached_cache_key(): """ - class MockFile(object): + class MockFile: def __init__(self, name): self.name = name diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index b937aa5a..09ceacf4 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -9,7 +9,7 @@ from .utils import create_image -class ImageGenerator(object): +class ImageGenerator: def generate(self): return create_image() From 762f9990e9c20824db005798626ece030da89cd4 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 17:01:59 +0200 Subject: [PATCH 495/527] Use dict/set literals/comprehensions --- imagekit/specs/__init__.py | 2 +- imagekit/specs/sourcegroups.py | 26 ++++++++++++++------------ imagekit/templatetags/imagekit.py | 16 ++++++---------- tests/test_generateimage_tag.py | 2 +- tests/test_thumbnail_tag.py | 2 +- 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 96c97282..36befb86 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -203,7 +203,7 @@ class SpecHost: """ def __init__(self, spec=None, spec_id=None, **kwargs): - spec_attrs = dict((k, v) for k, v in kwargs.items() if v is not None) + spec_attrs = {k: v for k, v in kwargs.items() if v is not None} if spec_attrs: if spec: diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 47fb168a..8dc1a1fa 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -74,9 +74,9 @@ def update_source_hashes(self, instance): """ self.init_instance(instance) - instance._ik['source_hashes'] = dict( - (attname, hash(getattr(instance, attname))) - for attname in self.get_source_fields(instance)) + instance._ik['source_hashes'] = { + attname: hash(getattr(instance, attname)) + for attname in self.get_source_fields(instance)} return instance._ik['source_hashes'] def get_source_fields(self, instance): @@ -84,9 +84,10 @@ def get_source_fields(self, instance): Returns a list of the source fields for the given instance. """ - return set(src.image_field - for src in self._source_groups - if isinstance(instance, src.model_class)) + return { + src.image_field + for src in self._source_groups + if isinstance(instance, src.model_class)} @ik_model_receiver def post_save_receiver(self, sender, instance=None, created=False, update_fields=None, raw=False, **kwargs): @@ -107,12 +108,13 @@ def post_save_receiver(self, sender, instance=None, created=False, update_fields def post_init_receiver(self, sender, instance=None, **kwargs): self.init_instance(instance) source_fields = self.get_source_fields(instance) - local_fields = dict((field.name, field) - for field in instance._meta.local_fields - if field.name in source_fields) - instance._ik['source_hashes'] = dict( - (attname, hash(file_field)) - for attname, file_field in local_fields.items()) + local_fields = { + field.name: field + for field in instance._meta.local_fields + if field.name in source_fields} + instance._ik['source_hashes'] = { + attname: hash(file_field) + for attname, file_field in local_fields.items()} def dispatch_signal(self, signal, file, model_class, instance, attname): """ diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 6513a553..4c2cc2ac 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -17,7 +17,7 @@ def get_cachefile(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) - kwargs = dict((k, v.resolve(context)) for k, v in generator_kwargs.items()) + kwargs = {k: v.resolve(context) for k, v in generator_kwargs.items()} generator = generator_registry.get(generator_id, **kwargs) return ImageCacheFile(generator) @@ -30,7 +30,7 @@ def parse_dimensions(dimensions): """ width, height = [d.strip() and int(d) or None for d in dimensions.split('x')] - return dict(width=width, height=height) + return {'width': width, 'height': height} class GenerateImageAssignmentNode(template.Node): @@ -60,8 +60,7 @@ def __init__(self, generator_id, generator_kwargs, html_attrs): def render(self, context): file = get_cachefile(context, self._generator_id, self._generator_kwargs) - attrs = dict((k, v.resolve(context)) for k, v in - self._html_attrs.items()) + attrs = {k: v.resolve(context) for k, v in self._html_attrs.items()} # Only add width and height if neither is specified (to allow for # proportional in-browser scaling). @@ -90,8 +89,7 @@ def render(self, context): variable_name = self.get_variable_name(context) generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR - kwargs = dict((k, v.resolve(context)) for k, v in - self._generator_kwargs.items()) + kwargs = {k: v.resolve(context) for k, v in self._generator_kwargs.items()} kwargs['source'] = self._source.resolve(context) kwargs.update(parse_dimensions(self._dimensions.resolve(context))) generator = generator_registry.get(generator_id, **kwargs) @@ -113,16 +111,14 @@ def __init__(self, generator_id, dimensions, source, generator_kwargs, html_attr def render(self, context): generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR dimensions = parse_dimensions(self._dimensions.resolve(context)) - kwargs = dict((k, v.resolve(context)) for k, v in - self._generator_kwargs.items()) + kwargs = {k: v.resolve(context) for k, v in self._generator_kwargs.items()} kwargs['source'] = self._source.resolve(context) kwargs.update(dimensions) generator = generator_registry.get(generator_id, **kwargs) file = ImageCacheFile(generator) - attrs = dict((k, v.resolve(context)) for k, v in - self._html_attrs.items()) + attrs = {k: v.resolve(context) for k, v in self._html_attrs.items()} # Only add width and height if neither is specified (to allow for # proportional in-browser scaling). diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index ffcbb306..eb2b7ad4 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -9,7 +9,7 @@ def test_img_tag(): ttag = r"""{% generateimage 'testspec' source=img %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - expected_attrs = set(['src', 'width', 'height']) + expected_attrs = {'src', 'width', 'height'} assert set(attrs.keys()) == expected_attrs for k in expected_attrs: assert attrs[k].strip() != '' diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index c1cf0ea6..9c80fe13 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -9,7 +9,7 @@ def test_img_tag(): ttag = r"""{% thumbnail '100x100' img %}""" clear_imagekit_cache() attrs = get_html_attrs(ttag) - expected_attrs = set(['src', 'width', 'height']) + expected_attrs = {'src', 'width', 'height'} assert set(attrs.keys()) == expected_attrs for k in expected_attrs: assert attrs[k].strip() != '' From 2c7c97f3a2a5835c70c5754a79eaca0504356fec Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Thu, 14 Oct 2021 16:43:44 +0200 Subject: [PATCH 496/527] Do not call getattr with a constant attribute value, it is not any safer than normal property access. --- imagekit/specs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 36befb86..6532a096 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -123,7 +123,7 @@ def __getstate__(self): # yet, preventing us from accessing the source field. # (This is issue #234.) if isinstance(self.source, ImageFieldFile): - field = getattr(self.source, 'field') + field = self.source.field state['_field_data'] = { 'instance': getattr(self.source, 'instance', None), 'attname': getattr(field, 'name', None), From 04920e4d3693b00617a51939059ae45e4cb09232 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 12:02:41 +0100 Subject: [PATCH 497/527] Prefer not in --- imagekit/templatetags/imagekit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 4c2cc2ac..f9e5806e 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -64,7 +64,7 @@ def render(self, context): # Only add width and height if neither is specified (to allow for # proportional in-browser scaling). - if not 'width' in attrs and not 'height' in attrs: + if 'width' not in attrs and 'height' not in attrs: attrs.update(width=file.width, height=file.height) attrs['src'] = file.url @@ -122,7 +122,7 @@ def render(self, context): # Only add width and height if neither is specified (to allow for # proportional in-browser scaling). - if not 'width' in attrs and not 'height' in attrs: + if 'width' not in attrs and 'height' not in attrs: attrs.update(width=file.width, height=file.height) attrs['src'] = file.url From e7c562cff43d07becb51ed7a50c5e12e9ba6c910 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 12:03:06 +0100 Subject: [PATCH 498/527] Small whitespace and line length fixes --- imagekit/processors/__init__.py | 16 ++++++++-------- imagekit/specs/__init__.py | 3 ++- imagekit/utils.py | 3 ++- setup.py | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/imagekit/processors/__init__.py b/imagekit/processors/__init__.py index 7c3532f0..b0195d9e 100644 --- a/imagekit/processors/__init__.py +++ b/imagekit/processors/__init__.py @@ -1,12 +1,12 @@ from pilkit.processors import * __all__ = [ - # Base - 'ProcessorPipeline', 'Adjust', 'Reflection', 'Transpose', - 'Anchor', 'MakeOpaque', - # Crop - 'TrimBorderColor', 'Crop', 'SmartCrop', - # Resize - 'Resize', 'ResizeToCover', 'ResizeToFill', 'SmartResize', - 'ResizeCanvas', 'AddBorder', 'ResizeToFit', 'Thumbnail' + # Base + 'ProcessorPipeline', 'Adjust', 'Reflection', 'Transpose', + 'Anchor', 'MakeOpaque', + # Crop + 'TrimBorderColor', 'Crop', 'SmartCrop', + # Resize + 'Resize', 'ResizeToCover', 'ResizeToFill', 'SmartResize', + 'ResizeCanvas', 'AddBorder', 'ResizeToFit', 'Thumbnail' ] diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 6532a096..d06cf888 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -146,7 +146,8 @@ def generate(self): " with it." % self) # TODO: Move into a generator base class - # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) + # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. + # (The tricky part is how to deal with original_format since generator base class won't have one.) closed = self.source.closed if closed: diff --git a/imagekit/utils.py b/imagekit/utils.py index a28cd0b0..cd273c08 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -12,6 +12,7 @@ _autodiscovered = False + def get_nonabstract_descendants(model): """ Returns all non-abstract descendants of the model. """ if not model._meta.abstract: @@ -133,7 +134,7 @@ def sanitize_cache_key(key): # The also can't be > 250 chars long. Since we don't know what the # user's cache ``KEY_FUNCTION`` setting is like, we'll limit it to 200. if len(new_key) >= 200: - new_key = '%s:%s' % (new_key[:200-33], md5(key.encode('utf-8')).hexdigest()) + new_key = '%s:%s' % (new_key[:200 - 33], md5(key.encode('utf-8')).hexdigest()) key = new_key return key diff --git a/setup.py b/setup.py index 547d35fe..8cdaa3e3 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ def exec_file(filepath, globalz=None, localz=None): - exec(read(filepath), globalz, localz) + exec(read(filepath), globalz, localz) # Load package meta from the pkgmeta module without loading imagekit. From 65c0840a0b3e3fd3fa9befdc8ed2a3dcd5f29370 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 12:41:37 +0100 Subject: [PATCH 499/527] Remove workaround --- setup.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/setup.py b/setup.py index 8cdaa3e3..e1c37580 100644 --- a/setup.py +++ b/setup.py @@ -5,12 +5,6 @@ from setuptools import find_packages, setup -# Workaround for multiprocessing/nose issue. See http://bugs.python.org/msg170215 -try: - import multiprocessing # NOQA -except ImportError: - pass - if 'publish' in sys.argv: os.system('python setup.py sdist bdist_wheel upload') From 1b43ec92d29863ad95a32077d3b592bc44628054 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 12:43:44 +0100 Subject: [PATCH 500/527] Update setup.py --- setup.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index e1c37580..4c2d44bb 100644 --- a/setup.py +++ b/setup.py @@ -39,10 +39,8 @@ def exec_file(filepath, globalz=None, localz=None): zip_safe=False, include_package_data=True, install_requires=[ - "django-appconf>=0.5,<1.0.4; python_version<'3'", - "django-appconf; python_version>'3'", - 'pilkit>=0.2.0', - 'six', + 'django-appconf', + 'pilkit', ], extras_require={ 'async': ['django-celery>=3.0'], @@ -56,12 +54,6 @@ def exec_file(filepath, globalz=None, localz=None): 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', From beb5b6e9ee2b2d91ac3e57d245e7a6b61e6b5102 Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 20:49:58 +0100 Subject: [PATCH 501/527] Remove u'' prefix --- docs/conf.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 3e0009dd..06e90660 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # ImageKit documentation build configuration file, created by # sphinx-quickstart on Sun Sep 25 17:05:55 2011. @@ -44,8 +43,8 @@ master_doc = 'index' # General information about the project. -project = u'ImageKit' -copyright = u'2011, Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter' +project = 'ImageKit' +copyright = '2011, Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter' pkgmeta = {} execfile(os.path.join(os.path.dirname(__file__), '..', 'imagekit', @@ -191,8 +190,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'ImageKit.tex', u'ImageKit Documentation', - u'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett \\& Matthew Tretter', 'manual'), + ('index', 'ImageKit.tex', 'ImageKit Documentation', + 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett \\& Matthew Tretter', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -221,8 +220,8 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'imagekit', u'ImageKit Documentation', - [u'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter'], 1) + ('index', 'imagekit', 'ImageKit Documentation', + ['Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter'], 1) ] # If true, show URL addresses after external links. @@ -235,7 +234,7 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'ImageKit', u'ImageKit Documentation', u'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter', + ('index', 'ImageKit', 'ImageKit Documentation', 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter', 'ImageKit', 'One line description of project.', 'Miscellaneous'), ] From 1eeac9993edce6cf160e7a36dc9cce340b43770e Mon Sep 17 00:00:00 2001 From: Jaap Roes Date: Wed, 3 Nov 2021 20:50:08 +0100 Subject: [PATCH 502/527] Use yield from --- imagekit/registry.py | 3 +-- imagekit/utils.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index bcd3d22b..f7a5bca6 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -152,8 +152,7 @@ def unregister(self, generator_id, cachefiles): def get(self, generator_id): for k, v in self._cachefiles.items(): if generator_id in v: - for file in k(): - yield file + yield from k() class Register: diff --git a/imagekit/utils.py b/imagekit/utils.py index cd273c08..3f72c297 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -18,8 +18,7 @@ def get_nonabstract_descendants(model): if not model._meta.abstract: yield model for s in model.__subclasses__(): - for m in get_nonabstract_descendants(s): - yield m + yield from get_nonabstract_descendants(s) def get_by_qname(path, desc): From 2457071746c23fb90420620b1ec9a2b9861153f7 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sat, 13 Nov 2021 01:23:12 +0200 Subject: [PATCH 503/527] Properly close files after finish using them This change is mostly related to tests and setup.py. On the imagekit's own code base all files are properly closed. --- setup.py | 4 +++- tests/test_cachefiles.py | 4 ++-- tests/test_fields.py | 24 ++++++++++++++---------- tests/test_sourcegroups.py | 6 ++++-- tests/utils.py | 11 ++++++----- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/setup.py b/setup.py index 4c2d44bb..633e63d9 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,9 @@ sys.exit() -read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read() +def read(filepath): + with codecs.open(filepath, 'r', 'utf-8') as f: + return f.read() def exec_file(filepath, globalz=None, localz=None): diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index f7caf4f7..fa911deb 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -109,8 +109,8 @@ def test_lazyfile_stringification(): assert str(file) == '' assert repr(file) == '' - source_file = get_image_file() - file = LazyImageCacheFile('testspec', source=source_file) + with get_image_file() as source_file: + file = LazyImageCacheFile('testspec', source=source_file) file.name = 'a.jpg' assert str(file) == 'a.jpg' assert repr(file) == '' diff --git a/tests/test_fields.py b/tests/test_fields.py index d1eef1b8..47ba0d93 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -15,9 +15,9 @@ @pytest.mark.django_db(transaction=True) def test_model_processedimagefield(): instance = ProcessedImageFieldModel() - file = File(get_image_file()) - instance.processed.save('whatever.jpeg', file) - instance.save() + with File(get_image_file()) as file: + instance.processed.save('whatever.jpeg', file) + instance.save() assert instance.processed.width == 50 assert instance.processed.height == 50 @@ -26,9 +26,9 @@ def test_model_processedimagefield(): @pytest.mark.django_db(transaction=True) def test_model_processedimagefield_with_spec(): instance = ProcessedImageFieldWithSpecModel() - file = File(get_image_file()) - instance.processed.save('whatever.jpeg', file) - instance.save() + with File(get_image_file()) as file: + instance.processed.save('whatever.jpeg', file) + instance.save() assert instance.processed.width == 100 assert instance.processed.height == 60 @@ -38,15 +38,19 @@ def test_model_processedimagefield_with_spec(): def test_form_processedimagefield(): class TestForm(forms.ModelForm): image = ikforms.ProcessedImageField(spec_id='tests:testform_image', - processors=[SmartCrop(50, 50)], format='JPEG') + processors=[SmartCrop(50, 50)], + format='JPEG') class Meta: model = ImageModel fields = 'image', - upload_file = get_image_file() - file_dict = {'image': SimpleUploadedFile('abc.jpg', upload_file.read())} - form = TestForm({}, file_dict) + with get_image_file() as upload_file: + files = { + 'image': SimpleUploadedFile('abc.jpg', upload_file.read()) + } + + form = TestForm({}, files) instance = form.save() assert instance.image.width == 50 diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index 8e0b52f8..56174179 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -26,7 +26,8 @@ def test_source_saved_signal(): source_group = ImageFieldSourceGroup(ImageModel, 'image') receiver = make_counting_receiver(source_group) source_saved.connect(receiver) - ImageModel.objects.create(image=File(get_image_file(), name='reference.png')) + with File(get_image_file(), name='reference.png') as image: + ImageModel.objects.create(image=image) assert receiver.count == 1 @@ -56,5 +57,6 @@ def test_abstract_model_signals(): source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') receiver = make_counting_receiver(source_group) source_saved.connect(receiver) - ConcreteImageModel.objects.create(original_image=File(get_image_file(), name='reference.png')) + with File(get_image_file(), name='reference.png') as image: + ConcreteImageModel.objects.create(original_image=image) assert receiver.count == 1 diff --git a/tests/utils.py b/tests/utils.py index 0e91ecca..cc61e621 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -31,7 +31,8 @@ def get_image_file(): def get_unique_image_file(): file = NamedTemporaryFile() - file.write(get_image_file().read()) + with get_image_file() as image: + file.write(image.read()) return file @@ -60,10 +61,10 @@ def pickleback(obj): def render_tag(ttag): - img = get_image_file() - template = Template('{%% load imagekit %%}%s' % ttag) - context = Context({'img': img}) - return template.render(context) + with get_image_file() as img: + template = Template('{%% load imagekit %%}%s' % ttag) + context = Context({'img': img}) + return template.render(context) def get_html_attrs(ttag): From 7b56b2a24052e1de728b7f72f080d2348b52a8ae Mon Sep 17 00:00:00 2001 From: Julian Wachholz Date: Wed, 22 Dec 2021 18:32:24 +0100 Subject: [PATCH 504/527] Fix: only seek files when possible Also fixes #517 --- imagekit/cachefiles/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 00643d3d..67b8342c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -102,7 +102,8 @@ def _generate(self): actual_name = self.storage.save(self.name, content) # We're going to reuse the generated file, so we need to reset the pointer. - content.seek(0) + if not hasattr(content, "seekable") or content.seekable(): + content.seek(0) # Store the generated file. If we don't do this, the next time the # "file" attribute is accessed, it will result in a call to the storage From ed892718784a1f2c8ad516f978403786288b457c Mon Sep 17 00:00:00 2001 From: Arman Mazloumzadeh <44166374+armanexplorer@users.noreply.github.com> Date: Sun, 3 Apr 2022 08:23:16 +0430 Subject: [PATCH 505/527] Fix equality checking of paths by normalizing them --- imagekit/cachefiles/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 00643d3d..d74c51c4 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -1,3 +1,4 @@ +import os.path from copy import copy from django.conf import settings @@ -110,7 +111,13 @@ def _generate(self): # contents of the file, what would the point of that be? self.file = File(content) - if actual_name != self.name: + # ``actual_name`` holds the output of ``self.storage.save()`` that + # by default returns filenames with forward slashes, even on windows. + # On the other hand, ``self.name`` holds OS-specific paths results + # from applying path normalizers like ``os.path.normpath()`` in the + # ``namer``. So, the filenames should be normalized before their + # equality checking. + if os.path.normpath(actual_name) != os.path.normpath(self.name): get_logger().warning( 'The storage backend %s did not save the file with the' ' requested name ("%s") and instead used "%s". This may be' From 2ccf78760ac9b9cd8f95740c1912dce37b8e7d42 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Sun, 7 Aug 2022 07:04:52 +1000 Subject: [PATCH 506/527] docs: Fix a few typos There are small typos in: - docs/_themes/README.rst - docs/caching.rst - imagekit/files.py - imagekit/forms/fields.py - imagekit/specs/sourcegroups.py - tests/test_optimistic_strategy.py Fixes: - Should read `underlying` rather than `underlaying`. - Should read `truthiness` rather than `thruthiness`. - Should read `separate` rather than `seprate`. - Should read `response` rather than `responce`. - Should read `represents` rather than `repesents`. - Should read `perform` rather than `peform`. - Should read `directly` rather than `dirrectly`. - Should read `derivative` rather than `drivative`. Signed-off-by: Tim Gates --- docs/_themes/README.rst | 2 +- docs/caching.rst | 6 +++--- imagekit/files.py | 2 +- imagekit/forms/fields.py | 2 +- imagekit/specs/sourcegroups.py | 2 +- tests/test_optimistic_strategy.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/_themes/README.rst b/docs/_themes/README.rst index e8179f96..26172c76 100755 --- a/docs/_themes/README.rst +++ b/docs/_themes/README.rst @@ -2,7 +2,7 @@ krTheme Sphinx Style ==================== This repository contains sphinx styles Kenneth Reitz uses in most of -his projects. It is a drivative of Mitsuhiko's themes for Flask and Flask related +his projects. It is a derivative of Mitsuhiko's themes for Flask and Flask related projects. To use this style in your Sphinx documentation, follow this guide: diff --git a/docs/caching.rst b/docs/caching.rst index 6b576fcc..30e93089 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -117,7 +117,7 @@ differently and for example do not cache values if timeout is ``None``. If you clear your cache durring deployment or some other reason probably you do not want to lose the cache for generated images especcialy if you are using some slow remote storage (like Amazon S3). Then you can configure -seprate cache (for example redis) in your ``CACHES`` config and tell ImageKit +separate cache (for example redis) in your ``CACHES`` config and tell ImageKit to use it instead of the default cache by setting ``IMAGEKIT_CACHE_BACKEND``. @@ -180,7 +180,7 @@ Or, in Python: If you are using an "async" backend in combination with the "optimistic" cache file strategy (see `Removing Safeguards`_ below), checking for - thruthiness as described above will not work. The "optimistic" backend is + truthiness as described above will not work. The "optimistic" backend is very optimistic so to say, and removes the check. Create and use the following strategy to a) have images only created on save, and b) retain the ability to check whether the images have already been created:: @@ -211,7 +211,7 @@ operation. However, if the state isn't cached, ImageKit will need to query the storage backend. For those who aren't willing to accept that cost (and who never want ImageKit -to generate images in the request-responce cycle), there's the "optimistic" +to generate images in the request-response cycle), there's the "optimistic" cache file strategy. This strategy only generates a new image when a spec's source image is created or changed. Unlike with the "just in time" strategy, accessing the file won't cause it to be generated, ImageKit will just assume diff --git a/imagekit/files.py b/imagekit/files.py index f317c5e3..8823c589 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -57,7 +57,7 @@ def open(self, mode='rb'): try: self.file.open(mode) except ValueError: - # if the underlaying file can't be reopened + # if the underlying file can't be reopened # then we will use the storage to try to open it again if self.file.closed: # clear cached file instance diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index 81d42979..cd155466 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -27,7 +27,7 @@ def clean(self, data, initial=None): spec = self.get_spec(source=data) f = generate(spec) # Name is required in Django 1.4. When we drop support for it - # then we can dirrectly return the result from `generate(spec)` + # then we can directly return the result from `generate(spec)` f.name = data.name return f diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 8dc1a1fa..2e3e7c4a 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -130,7 +130,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): class ImageFieldSourceGroup: """ - A source group that repesents a particular field across all instances of a + A source group that represents a particular field across all instances of a model and its subclasses. """ diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index 09ceacf4..7b321232 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -30,7 +30,7 @@ def get_image_cache_file(): def test_no_io_on_bool(): """ When checking the truthiness of an ImageCacheFile, the storage shouldn't - peform IO operations. + perform IO operations. """ file = get_image_cache_file() From d4690698cc73760586e6574df62fe5497550aec2 Mon Sep 17 00:00:00 2001 From: Alexandre Spaeth Date: Mon, 24 Apr 2023 16:48:47 -0700 Subject: [PATCH 507/527] Upgrade project to latest versions of python and django --- imagekit/conf.py | 5 ++++- tox.ini | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 9d2ca1f3..beadde49 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -36,5 +36,8 @@ def configure_cache_timeout(self, value): def configure_default_file_storage(self, value): if value is None: - value = settings.DEFAULT_FILE_STORAGE + try: + value = settings.STORAGES["default"]["BACKEND"] + except AttributeError: + value = settings.DEFAULT_FILE_STORAGE return value diff --git a/tox.ini b/tox.ini index 4e075c1c..9e9da6d7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,23 +1,23 @@ [tox] envlist = - py{36,37,38,39,310}-django{22,31,32}, + py{37,38,39,310,311}-django{32,41,42}, py310-djangomain, coverage-report [gh-actions] python = - 3.6: py36 3.7: py37 3.8: py38 3.9: py39 - 3.10: py310, coverage-report + 3.10: py310 + 3.11: py311, coverage-report [testenv] deps = -r test-requirements.txt - django22: django~=2.2.0 - django31: django~=3.1.0 django32: django~=3.2.0 + django41: django~=4.1.0 + django42: django~=4.2.0 djangomain: https://github.com/django/django/archive/refs/heads/main.zip setenv = COVERAGE_FILE=.coverage.{envname} From e46d7c7e3cd65476730abc88da7a2431c98efe3f Mon Sep 17 00:00:00 2001 From: Alexandre Spaeth Date: Mon, 24 Apr 2023 16:53:44 -0700 Subject: [PATCH 508/527] Use proper envlist matrix --- tox.ini | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 9e9da6d7..bcf55e8e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,11 @@ [tox] envlist = - py{37,38,39,310,311}-django{32,41,42}, - py310-djangomain, + py37-django{32} + py38-django{42, 41, 32} + py39-django{42, 41, 32} + py310-django{42, 41, 32} + py311-django{42, 41} + py311-djangomain, coverage-report [gh-actions] From c309837b72a9f158887fb204014eead1fe990953 Mon Sep 17 00:00:00 2001 From: Alexandre Spaeth Date: Thu, 27 Apr 2023 09:55:11 -0700 Subject: [PATCH 509/527] Fix github workflow python versions --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 847d3a9b..5feffc1a 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.6', '3.7', '3.8', '3.9', '3.10'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] steps: - uses: actions/checkout@v2 From e86a40b13a458fa44976fc5d609b93a6944c4583 Mon Sep 17 00:00:00 2001 From: Alexandre Spaeth Date: Thu, 27 Apr 2023 11:47:19 -0700 Subject: [PATCH 510/527] Add tests for new Django 4.2 settings --- tests/test_settings.py | 32 ++++++++++++++++++++++++++++++++ tests/utils.py | 5 +++++ 2 files changed, 37 insertions(+) create mode 100644 tests/test_settings.py diff --git a/tests/test_settings.py b/tests/test_settings.py new file mode 100644 index 00000000..d6aa2674 --- /dev/null +++ b/tests/test_settings.py @@ -0,0 +1,32 @@ +import django +from django.test import override_settings +import pytest +from imagekit.conf import ImageKitConf, settings + + +@pytest.mark.skipif( + django.VERSION < (4, 2), + reason="STORAGES was introduced in Django 4.2", +) +def test_custom_storages(): + with override_settings( + STORAGES={ + "default": { + "BACKEND": "tests.utils.CustomStorage", + } + }, + ): + conf = ImageKitConf() + assert conf.configure_default_file_storage(None) == "tests.utils.CustomStorage" + + +@pytest.mark.skipif( + django.VERSION >= (5, 1), + reason="DEFAULT_FILE_STORAGE is removed in Django 5.1.", +) +def test_custom_default_file_storage(): + with override_settings(DEFAULT_FILE_STORAGE="tests.utils.CustomStorage"): + # If we don’t remove this, Django 4.2 will keep the old value. + del settings.STORAGES + conf = ImageKitConf() + assert conf.configure_default_file_storage(None) == "tests.utils.CustomStorage" diff --git a/tests/utils.py b/tests/utils.py index cc61e621..1909772e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,6 +6,7 @@ from bs4 import BeautifulSoup from django.core.files import File +from django.core.files.storage import FileSystemStorage from django.template import Context, Template from PIL import Image @@ -79,6 +80,10 @@ def assert_file_is_truthy(file): assert bool(file), 'File is not truthy' +class CustomStorage(FileSystemStorage): + pass + + class DummyAsyncCacheFileBackend(Simple): """ A cache file backend meant to simulate async generation. From 7dde620d60ef0685c7ca3fb10a833830e7646e1f Mon Sep 17 00:00:00 2001 From: Tim Schilling Date: Fri, 10 Jan 2020 13:55:49 -0600 Subject: [PATCH 511/527] Convert the anchor kwarg from SafeString to str. --- imagekit/templatetags/imagekit.py | 10 ++++++++++ tests/test_thumbnail_tag.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index f9e5806e..b2bbfe72 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -92,6 +92,11 @@ def render(self, context): kwargs = {k: v.resolve(context) for k, v in self._generator_kwargs.items()} kwargs['source'] = self._source.resolve(context) kwargs.update(parse_dimensions(self._dimensions.resolve(context))) + if kwargs.get('anchor'): + # ImageKit uses pickle at protocol 0, which throws infinite + # recursion errors when anchor is set to a SafeString instance. + # This converts the SafeString into a str instance. + kwargs['anchor'] = kwargs['anchor'][:] generator = generator_registry.get(generator_id, **kwargs) context[variable_name] = ImageCacheFile(generator) @@ -114,6 +119,11 @@ def render(self, context): kwargs = {k: v.resolve(context) for k, v in self._generator_kwargs.items()} kwargs['source'] = self._source.resolve(context) kwargs.update(dimensions) + if kwargs.get('anchor'): + # ImageKit uses pickle at protocol 0, which throws infinite + # recursion errors when anchor is set to a SafeString instance. + # This converts the SafeString into a str instance. + kwargs['anchor'] = kwargs['anchor'][:] generator = generator_registry.get(generator_id, **kwargs) file = ImageCacheFile(generator) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 9c80fe13..f3bdfda6 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -15,6 +15,16 @@ def test_img_tag(): assert attrs[k].strip() != '' +def test_img_tag_anchor(): + ttag = r"""{% thumbnail '100x100' img anchor='c' %}""" + clear_imagekit_cache() + attrs = get_html_attrs(ttag) + expected_attrs = {'src', 'width', 'height'} + assert set(attrs.keys()) == expected_attrs + for k in expected_attrs: + assert attrs[k].strip() != '' + + def test_img_tag_attrs(): ttag = r"""{% thumbnail '100x100' img -- alt="Hello" %}""" clear_imagekit_cache() @@ -58,6 +68,13 @@ def test_assignment_tag(): assert html != '' +def test_assignment_tag_anchor(): + ttag = r"""{% thumbnail '100x100' img anchor='c' as th %}{{ th.url }}""" + clear_imagekit_cache() + html = render_tag(ttag) + assert html != '' + + def test_single_dimension(): ttag = r"""{% thumbnail '100x' img as th %}{{ th.width }}""" clear_imagekit_cache() From 5cdcbb203e19c65fa309732230baf060fbf82fb6 Mon Sep 17 00:00:00 2001 From: Alexandre Spaeth Date: Tue, 9 May 2023 14:32:10 -0700 Subject: [PATCH 512/527] Refactor how we get the default storage class --- docs/configuration.rst | 13 +++++++++- imagekit/cachefiles/__init__.py | 17 +++++------- imagekit/conf.py | 8 +++--- imagekit/utils.py | 16 ++++++++++++ tests/test_settings.py | 46 +++++++++++++++++++++++++++++++-- tests/test_utils.py | 42 ++++++++++++++++++++++++++++++ 6 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 tests/test_utils.py diff --git a/docs/configuration.rst b/docs/configuration.rst index 236191e3..84636cee 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -21,12 +21,23 @@ Settings :default: ``None`` + Starting with Django 4.2, if you defined ``settings.STORAGES``: + the Django storage backend alias to retrieve the storage instance defined + in your settings, as described in the `Django file storage documentation`_. + If no value is provided for ``IMAGEKIT_DEFAULT_FILE_STORAGE``, + and none is specified by the spec definition, the ``default`` file storage + will be used. + + Before Django 4.2, or if ``settings.STORAGES`` is not defined: The qualified class name of a Django storage backend to use to save the cached images. If no value is provided for ``IMAGEKIT_DEFAULT_FILE_STORAGE``, and none is specified by the spec definition, `your default file storage`__ will be used. +.. _`Django file storage documentation`: https://docs.djangoproject.com/en/dev/ref/files/storage/ + + .. attribute:: IMAGEKIT_DEFAULT_CACHEFILE_BACKEND :default: ``'imagekit.cachefiles.backends.Simple'`` @@ -52,7 +63,7 @@ Settings The cache is then used to store information like the state of cached images (i.e. validated or not). -.. _`Django cache section`: https://docs.djangoproject.com/en/1.8/topics/cache/#accessing-the-cache +.. _`Django cache section`: https://docs.djangoproject.com/en/dev/topics/cache/#accessing-the-cache .. attribute:: IMAGEKIT_CACHE_TIMEOUT diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 7326ebd9..3d036fd1 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -10,7 +10,9 @@ from ..files import BaseIKFile from ..registry import generator_registry from ..signals import content_required, existence_required -from ..utils import generate, get_by_qname, get_logger, get_singleton +from ..utils import ( + generate, get_by_qname, get_logger, get_singleton, get_storage +) class ImageCacheFile(BaseIKFile, ImageFile): @@ -44,8 +46,7 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c self.name = name storage = (callable(storage) and storage()) or storage or \ - getattr(generator, 'cachefile_storage', None) or get_singleton( - settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') + getattr(generator, 'cachefile_storage', None) or get_storage() self.cachefile_backend = ( cachefile_backend or getattr(generator, 'cachefile_backend', None) @@ -156,20 +157,14 @@ def __getstate__(self): # remove storage from state as some non-FileSystemStorage can't be # pickled - settings_storage = get_singleton( - settings.IMAGEKIT_DEFAULT_FILE_STORAGE, - 'file storage backend' - ) + settings_storage = get_storage() if state['storage'] == settings_storage: state.pop('storage') return state def __setstate__(self, state): if 'storage' not in state: - state['storage'] = get_singleton( - settings.IMAGEKIT_DEFAULT_FILE_STORAGE, - 'file storage backend' - ) + state['storage'] = get_storage() self.__dict__.update(state) def __repr__(self): diff --git a/imagekit/conf.py b/imagekit/conf.py index beadde49..786aeb34 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -37,7 +37,9 @@ def configure_cache_timeout(self, value): def configure_default_file_storage(self, value): if value is None: try: - value = settings.STORAGES["default"]["BACKEND"] - except AttributeError: - value = settings.DEFAULT_FILE_STORAGE + from django.conf import DEFAULT_STORAGE_ALIAS + except ImportError: # Django < 4.2 + return settings.DEFAULT_FILE_STORAGE + else: + return DEFAULT_STORAGE_ALIAS return value diff --git a/imagekit/utils.py b/imagekit/utils.py index 3f72c297..08f4aac2 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -125,6 +125,22 @@ def get_cache(): return caches[settings.IMAGEKIT_CACHE_BACKEND] +def get_storage(): + try: + from django.core.files.storage import storages, InvalidStorageError + except ImportError: # Django < 4.2 + return get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend' + ) + else: + try: + return storages[settings.IMAGEKIT_DEFAULT_FILE_STORAGE] + except InvalidStorageError: + return get_singleton( + settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend' + ) + + def sanitize_cache_key(key): if settings.IMAGEKIT_USE_MEMCACHED_SAFE_CACHE_KEY: # Memcached keys can't contain whitespace or control characters. diff --git a/tests/test_settings.py b/tests/test_settings.py index d6aa2674..2cf49301 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -2,6 +2,7 @@ from django.test import override_settings import pytest from imagekit.conf import ImageKitConf, settings +from imagekit.utils import get_storage @pytest.mark.skipif( @@ -17,7 +18,7 @@ def test_custom_storages(): }, ): conf = ImageKitConf() - assert conf.configure_default_file_storage(None) == "tests.utils.CustomStorage" + assert conf.configure_default_file_storage(None) == "default" @pytest.mark.skipif( @@ -29,4 +30,45 @@ def test_custom_default_file_storage(): # If we don’t remove this, Django 4.2 will keep the old value. del settings.STORAGES conf = ImageKitConf() - assert conf.configure_default_file_storage(None) == "tests.utils.CustomStorage" + + if django.VERSION >= (4, 2): + assert conf.configure_default_file_storage(None) == "default" + else: + assert ( + conf.configure_default_file_storage(None) == "tests.utils.CustomStorage" + ) + + +def test_get_storage_default(): + from django.core.files.storage import FileSystemStorage + + assert isinstance(get_storage(), FileSystemStorage) + + +@pytest.mark.skipif( + django.VERSION >= (5, 1), + reason="DEFAULT_FILE_STORAGE is removed in Django 5.1.", +) +def test_get_storage_custom_path(): + from tests.utils import CustomStorage + + with override_settings(IMAGEKIT_DEFAULT_FILE_STORAGE="tests.utils.CustomStorage"): + assert isinstance(get_storage(), CustomStorage) + + +@pytest.mark.skipif( + django.VERSION < (4, 2), + reason="STORAGES was introduced in Django 4.2", +) +def test_get_storage_custom_key(): + from tests.utils import CustomStorage + + with override_settings( + STORAGES={ + "custom": { + "BACKEND": "tests.utils.CustomStorage", + } + }, + IMAGEKIT_DEFAULT_FILE_STORAGE="custom", + ): + assert isinstance(get_storage(), CustomStorage) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000..0bac5dc8 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,42 @@ +import django +from django.test import override_settings +import pytest +from imagekit.utils import get_storage + + +def test_get_storage_default(): + from django.core.files.storage import default_storage + + if django.VERSION >= (4, 2): + assert get_storage() == default_storage + else: + assert isinstance(get_storage(), type(default_storage._wrapped)) + + +@pytest.mark.skipif( + django.VERSION >= (5, 1), + reason="DEFAULT_FILE_STORAGE is removed in Django 5.1.", +) +def test_get_storage_custom_import_path(): + from tests.utils import CustomStorage + + with override_settings(IMAGEKIT_DEFAULT_FILE_STORAGE="tests.utils.CustomStorage"): + assert isinstance(get_storage(), CustomStorage) + + +@pytest.mark.skipif( + django.VERSION < (4, 2), + reason="STORAGES was introduced in Django 4.2", +) +def test_get_storage_custom_key(): + from tests.utils import CustomStorage + + with override_settings( + STORAGES={ + "custom": { + "BACKEND": "tests.utils.CustomStorage", + } + }, + IMAGEKIT_DEFAULT_FILE_STORAGE="custom", + ): + assert isinstance(get_storage(), CustomStorage) From 5bcd97358f498d94fc01538df89565bbd0a3f038 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 28 Sep 2023 03:15:31 +0300 Subject: [PATCH 513/527] Update setup.py - Use build and twine to publish - Change maintainer metadate - Update classifiers --- setup.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 633e63d9..e1024819 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,8 @@ if 'publish' in sys.argv: - os.system('python setup.py sdist bdist_wheel upload') + os.system('python3 -m build') + os.system('python3 -m twine upload --repository django_imagekit dist/*') sys.exit() @@ -22,8 +23,10 @@ def exec_file(filepath, globalz=None, localz=None): # Load package meta from the pkgmeta module without loading imagekit. pkgmeta = {} -exec_file(os.path.join(os.path.dirname(__file__), - 'imagekit', 'pkgmeta.py'), pkgmeta) +exec_file( + os.path.join(os.path.dirname(__file__), 'imagekit', 'pkgmeta.py'), + pkgmeta +) setup( @@ -33,8 +36,8 @@ def exec_file(filepath, globalz=None, localz=None): long_description=read(os.path.join(os.path.dirname(__file__), 'README.rst')), author='Matthew Tretter', author_email='m@tthewwithanm.com', - maintainer='Bryan Veloso', - maintainer_email='bryan@revyver.com', + maintainer='Venelin Stoykov', + maintainer_email='venelin.stoykov@industria.tech', license='BSD', url='http://github.com/matthewwithanm/django-imagekit/', packages=find_packages(exclude=['*.tests', '*.tests.*', 'tests.*', 'tests']), @@ -56,11 +59,15 @@ def exec_file(filepath, globalz=None, localz=None): 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', 'Topic :: Utilities' ], ) From 07f2b3c964d1943043d432556551dd60a0a9ca41 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 28 Sep 2023 03:17:11 +0300 Subject: [PATCH 514/527] Bump version to 5.0.0 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 4745e7bd..a38778cc 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '4.1.0' +__version__ = '5.0.0' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 366687a75b626b8e184e71dce4db211af6eaf44e Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Thu, 20 Jun 2024 16:51:33 +0200 Subject: [PATCH 515/527] Add way to specify thumbnail format --- docs/configuration.rst | 7 +++++++ imagekit/generatorlibrary.py | 5 ++++- imagekit/templatetags/imagekit.py | 6 +++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 84636cee..f6b6028a 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -10,6 +10,13 @@ Settings .. currentmodule:: django.conf.settings +.. attribute:: IMAGEKIT_DEFAULT_THUMBNAIL_FORMAT + + :default: ``None`` + + The output format of the images generated by the ``thumbnail`` template tag. + + .. attribute:: IMAGEKIT_CACHEFILE_DIR :default: ``'CACHE/images'`` diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index 59f71ef6..dd5466fa 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -1,13 +1,16 @@ from .processors import Thumbnail as ThumbnailProcessor from .registry import register from .specs import ImageSpec +from django.conf import settings +default_thumbnail_format = getattr(settings, 'IMAGEKIT_DEFAULT_THUMBNAIL_FORMAT', None) class Thumbnail(ImageSpec): - def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, **kwargs): + def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, format=default_thumbnail_format, **kwargs): self.processors = [ThumbnailProcessor(width, height, anchor=anchor, crop=crop, upscale=upscale)] super().__init__(**kwargs) + self.format = format register.generator('imagekit:thumbnail', Thumbnail) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index b2bbfe72..07229091 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -97,6 +97,8 @@ def render(self, context): # recursion errors when anchor is set to a SafeString instance. # This converts the SafeString into a str instance. kwargs['anchor'] = kwargs['anchor'][:] + if kwargs.get('format'): + kwargs['format'] = kwargs['format'][:] generator = generator_registry.get(generator_id, **kwargs) context[variable_name] = ImageCacheFile(generator) @@ -124,6 +126,8 @@ def render(self, context): # recursion errors when anchor is set to a SafeString instance. # This converts the SafeString into a str instance. kwargs['anchor'] = kwargs['anchor'][:] + if kwargs.get('format'): + kwargs['format'] = kwargs['format'][:] generator = generator_registry.get(generator_id, **kwargs) file = ImageCacheFile(generator) @@ -241,7 +245,7 @@ def thumbnail(parser, token): The thumbnail tag supports the "--" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the - kwargs "anchor", and "crop". + kwargs "format", "anchor", and "crop". To use "smart cropping" (the ``SmartResize`` processor):: From 02d60e20a198483b24c07ed4e202b7a95f85c4c2 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 26 Jun 2024 10:28:14 +0200 Subject: [PATCH 516/527] Make it possible to generate srcset with the thumbnail template tag --- docs/configuration.rst | 9 +++++++++ imagekit/templatetags/imagekit.py | 27 ++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 84636cee..c2733c54 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -17,6 +17,15 @@ Settings The directory to which image files will be cached. +.. attribute:: IMAGEKIT_DEFAULT_THUMBNAIL_SRCSET_SCALES + + :default: ``None`` + + A list of scale factors, for example ``[2, 3]``. If specified, every + ```` generated by the ``thumbnail`` template tag will have a ``srcset`` + attribute with the given scales. To prevent this, set ``srcset=None``. + + .. attribute:: IMAGEKIT_DEFAULT_FILE_STORAGE :default: ``None`` diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index b2bbfe72..51dab481 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -3,6 +3,7 @@ from django.utils.encoding import force_str from django.utils.html import escape from django.utils.safestring import mark_safe +from django.conf import settings from ..cachefiles import ImageCacheFile from ..registry import generator_registry @@ -13,6 +14,7 @@ ASSIGNMENT_DELIMETER = 'as' HTML_ATTRS_DELIMITER = '--' DEFAULT_THUMBNAIL_GENERATOR = 'imagekit:thumbnail' +default_thumbnail_srcset_scales = getattr(settings, 'IMAGEKIT_DEFAULT_THUMBNAIL_SRCSET_SCALES', None) def get_cachefile(context, generator_id, generator_kwargs, source=None): @@ -124,9 +126,25 @@ def render(self, context): # recursion errors when anchor is set to a SafeString instance. # This converts the SafeString into a str instance. kwargs['anchor'] = kwargs['anchor'][:] + srcset_scales = default_thumbnail_srcset_scales + if "srcset" in kwargs: + if kwargs['srcset'] is not None: + srcset_scales = list(map(float, kwargs['srcset'].split())) + else: + srcset_scales = None + kwargs.pop("srcset") generator = generator_registry.get(generator_id, **kwargs) file = ImageCacheFile(generator) + srcset = [] + if srcset_scales: + for scale in srcset_scales: + scaled_kwargs = dict(kwargs) + if scaled_kwargs.get("height"): + scaled_kwargs["height"] = int(scaled_kwargs["height"] * scale) + if scaled_kwargs.get("width"): + scaled_kwargs["width"] = int(scaled_kwargs["width"] * scale) + srcset.append(ImageCacheFile(generator_registry.get(generator_id, **scaled_kwargs))) attrs = {k: v.resolve(context) for k, v in self._html_attrs.items()} @@ -136,6 +154,9 @@ def render(self, context): attrs.update(width=file.width, height=file.height) attrs['src'] = file.url + if len(srcset) > 0: + attrs['srcset'] = f'{file.url} 1x , ' + ' , '.join( + f'{entry[0].url} {entry[1]}x' for entry in zip(srcset, srcset_scales)) attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in attrs.items()) return mark_safe('' % attr_str) @@ -241,7 +262,11 @@ def thumbnail(parser, token): The thumbnail tag supports the "--" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the - kwargs "anchor", and "crop". + kwargs "srcset", "anchor", and "crop". + + To use "srcset" (generating multiple thumbnails for different pixel densities) list the scale factors:: + + {% thumbnail '100x100' mymodel.profile_image srcset="http://github.com/service/http://github.com/2%203 " %} To use "smart cropping" (the ``SmartResize`` processor):: From 3cdeba85758040bfdbf2ccbc70e3db7131c778d9 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 8 Jul 2024 18:51:57 +0200 Subject: [PATCH 517/527] Add tests --- tests/test_thumbnail_tag.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index f3bdfda6..3cedf9b6 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -87,3 +87,10 @@ def test_alternate_generator(): clear_imagekit_cache() html = render_tag(ttag) assert html == '1' + + +def test_alternate_format(): + ttag = r"""{% thumbnail '100x' img format='webp' as th %}{{ th.url }}""" + clear_imagekit_cache() + html = render_tag(ttag) + assert html.endswith('webp') From 581127928507ad6f929b9671d36103d8e1fa3e09 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 8 Jul 2024 19:05:08 +0200 Subject: [PATCH 518/527] Add srcset tests --- tests/test_thumbnail_tag.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index f3bdfda6..adc7fb0b 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,4 +1,5 @@ import pytest +import re from django.template import TemplateSyntaxError from . import imagegenerators # noqa @@ -87,3 +88,11 @@ def test_alternate_generator(): clear_imagekit_cache() html = render_tag(ttag) assert html == '1' + + +def test_srcset_arg(): + ttag = r"""{% thumbnail '100x' img srcset="http://github.com/service/http://github.com/1.5%202 " %}""" + clear_imagekit_cache() + html = render_tag(ttag) + srcset_regex = re.compile('srcset="http://github.com/service/http://github.com/.*%201x%20 , http://github.com/.*%201//.5x%20 , http://github.com/.*%202.0x "') + assert srcset_regex.search(html) is not None From 3222418bec836609b324f7b5de142c9646aa91bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20K=C3=A1lm=C3=A1n?= Date: Fri, 9 May 2025 14:46:44 +0200 Subject: [PATCH 519/527] test newer Python and Django versions --- .coveragerc | 2 ++ .github/workflows/python.yml | 2 +- setup.py | 5 ++--- tox.ini | 18 +++++++++--------- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.coveragerc b/.coveragerc index 33d71ab8..aa8ce2ad 100644 --- a/.coveragerc +++ b/.coveragerc @@ -7,3 +7,5 @@ show_missing = true skip_empty = true skip_covered = true precision = 2 +omit = + tests/* diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 5feffc1a..927d09e6 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index e1024819..17a6c9c7 100644 --- a/setup.py +++ b/setup.py @@ -62,12 +62,11 @@ def exec_file(filepath, globalz=None, localz=None): 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Utilities' ], ) diff --git a/tox.ini b/tox.ini index bcf55e8e..eff9790a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,27 +1,27 @@ [tox] envlist = - py37-django{32} - py38-django{42, 41, 32} - py39-django{42, 41, 32} - py310-django{42, 41, 32} - py311-django{42, 41} - py311-djangomain, + django32-py{39,310} + django42-py{39,310,311,312} + django51-py{310,311,312,313} + django52-py{310,311,312,313} + djangomain-{312,313} coverage-report [gh-actions] python = - 3.7: py37 - 3.8: py38 3.9: py39 3.10: py310 3.11: py311, coverage-report + 3.12: py312 + 3.13: py313 [testenv] deps = -r test-requirements.txt django32: django~=3.2.0 - django41: django~=4.1.0 django42: django~=4.2.0 + django51: django~=5.1.0 + django52: django~=5.2.0 djangomain: https://github.com/django/django/archive/refs/heads/main.zip setenv = COVERAGE_FILE=.coverage.{envname} From 4f1926b838d614df5af3b68ebcd84062f3731934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20K=C3=A1lm=C3=A1n?= Date: Fri, 9 May 2025 15:26:02 +0200 Subject: [PATCH 520/527] better log message grouping --- imagekit/cachefiles/__init__.py | 10 +++++----- tests/test_cachefiles.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 3d036fd1..6717cb9a 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -126,11 +126,11 @@ def _generate(self): ' because a file already existed with the requested name. If' ' so, you may have meant to call generate() instead of' ' generate(force=True), or there may be a race condition in the' - ' file backend %s. The saved file will not be used.' % ( - self.storage, - self.name, actual_name, - self.cachefile_backend - ) + ' file backend %s. The saved file will not be used.', + self.storage, + self.name, + actual_name, + self.cachefile_backend ) def __bool__(self): diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index fa911deb..6b06a6ad 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,5 +1,6 @@ from hashlib import md5 from unittest import mock +import os import pytest from django.conf import settings @@ -114,3 +115,20 @@ def test_lazyfile_stringification(): file.name = 'a.jpg' assert str(file) == 'a.jpg' assert repr(file) == '' + + +def test_generate_file_already_exists(caplog): + spec = TestSpec(source=get_unique_image_file()) + file_1 = ImageCacheFile(spec) + file_1._generate() + # generate another cache image with the same name + file_2 = ImageCacheFile(spec, name=file_1.name) + file_2._generate() + + assert len(caplog.records) == 1 + storage, name, actual_name, cachefile_backend = caplog.records[0].args + assert storage == file_2.storage + assert name == file_2.name + assert actual_name != name + assert os.path.basename(actual_name) in storage.listdir(os.path.dirname(actual_name))[1] + assert cachefile_backend == file_2.cachefile_backend From dfbbf0b13b4f27bc641d773e38ca8c01fa3925d4 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sun, 3 Aug 2025 10:52:45 -0700 Subject: [PATCH 521/527] Fix Read the Docs Build (#582) Fixes #581. --- .readthedocs.yaml | 31 +++++++++++++++++++++++++++++++ AUTHORS | 4 ++-- docs/conf.py | 7 ++++--- 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..33295726 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,31 @@ +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "20" + # rust: "1.70" + # golang: "1.20" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + # fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +# python: +# install: +# - requirements: docs/requirements.txt diff --git a/AUTHORS b/AUTHORS index 5438b944..1e516114 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,6 +6,7 @@ HZDG_. Maintainers ----------- +* `Venelin Stoykov`_ * `Matthew Tretter`_ * `Bryan Veloso`_ * `Chris Drackett`_ @@ -28,7 +29,6 @@ Contributors * `Jannis Leidel`_ * `Sean Bell`_ * `Saul Shanabrook`_ -* `Venelin Stoykov`_ * `Jaap Roes`_ .. _Justin Driscoll: http://github.com/jdriscoll @@ -52,4 +52,4 @@ Contributors .. _Sean Bell: https://github.com/seanbell .. _Saul Shanabrook: https://github.com/saulshanabrook .. _Venelin Stoykov: https://github.com/vstoykov -.. Jaap Roes: https://github.com/jaap3 +.. _Jaap Roes: https://github.com/jaap3 diff --git a/docs/conf.py b/docs/conf.py index 06e90660..3fba84ea 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -44,11 +44,12 @@ # General information about the project. project = 'ImageKit' -copyright = '2011, Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter' +copyright = '2011, Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Venelin Stoykov & contributors' pkgmeta = {} -execfile(os.path.join(os.path.dirname(__file__), '..', 'imagekit', - 'pkgmeta.py'), pkgmeta) +pkgmeta_file = os.path.join(os.path.dirname(__file__), '..', 'imagekit', 'pkgmeta.py') +with open(pkgmeta_file, 'r') as f: + exec(f.read(), pkgmeta) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the From ef9f0ea4b1e770fe59f179c2122f4976e25cd505 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 14 Sep 2025 22:02:17 +0300 Subject: [PATCH 522/527] Support Python 3.14 --- .github/workflows/python.yml | 6 +++--- imagekit/hashers.py | 19 ++++++++++++++----- setup.py | 1 + tox.ini | 12 ++++++------ 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 927d09e6..10c10bbe 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -13,12 +13,12 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14.0-rc.2'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} diff --git a/imagekit/hashers.py b/imagekit/hashers.py index 9b9de6e9..0c1c69ed 100644 --- a/imagekit/hashers.py +++ b/imagekit/hashers.py @@ -1,3 +1,4 @@ +import sys from copy import copy from hashlib import md5 from io import BytesIO @@ -14,12 +15,20 @@ def save_set(self, obj): dispatch[set] = save_set - def save_dict(self, obj): - write = self.write - write(MARK + DICT) + if sys.version_info[:2] >= (3, 14): + def save_dict(self, obj): + write = self.write + write(MARK + DICT) - self.memoize(obj) - self._batch_setitems(sorted(obj.items())) + self.memoize(obj) + self._batch_setitems(sorted(obj.items()), obj) + else: + def save_dict(self, obj): + write = self.write + write(MARK + DICT) + + self.memoize(obj) + self._batch_setitems(sorted(obj.items())) dispatch[dict] = save_dict diff --git a/setup.py b/setup.py index 17a6c9c7..c31e0ab9 100644 --- a/setup.py +++ b/setup.py @@ -67,6 +67,7 @@ def exec_file(filepath, globalz=None, localz=None): 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3.14', 'Topic :: Utilities' ], ) diff --git a/tox.ini b/tox.ini index eff9790a..647cf6a0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,9 @@ [tox] envlist = - django32-py{39,310} - django42-py{39,310,311,312} - django51-py{310,311,312,313} - django52-py{310,311,312,313} - djangomain-{312,313} + django32-py3{9,10} + django42-py3{9,10,11,12} + django52-py3{10,11,12,13,14} + djangomain-py3{13,14} coverage-report [gh-actions] @@ -14,6 +13,7 @@ python = 3.11: py311, coverage-report 3.12: py312 3.13: py313 + 3.14: py314 [testenv] deps = @@ -25,7 +25,7 @@ deps = djangomain: https://github.com/django/django/archive/refs/heads/main.zip setenv = COVERAGE_FILE=.coverage.{envname} -commands = python -m pytest --cov --cov-report term-missing:skip-covered +commands = python -Wdefault -m pytest --cov --cov-report term-missing:skip-covered ignore_outcome = djangomain: true From 0cb11557bc88b2cf4181a547798c270e74d59f2d Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 25 Sep 2025 21:23:22 +0300 Subject: [PATCH 523/527] test:properly close files in tests This will remove ResourceWarning from happening when running tests with `-Wdefault` --- tests/test_cachefiles.py | 42 +++++++++++++++++-------------- tests/test_optimistic_strategy.py | 16 ++++++------ tests/test_serialization.py | 21 ++++++++-------- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 6b06a6ad..a05bf7a7 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -30,9 +30,10 @@ def test_sync_backend_truthiness(): is truthy. """ - spec = TestSpec(source=get_unique_image_file()) - file = ImageCacheFile(spec) - assert_file_is_truthy(file) + with get_unique_image_file() as source_file: + spec = TestSpec(source=source_file) + file = ImageCacheFile(spec) + assert_file_is_truthy(file) def test_async_backend_falsiness(): @@ -40,9 +41,10 @@ def test_async_backend_falsiness(): Ensure that a cachefile with an asynchronous cache file backend is falsy. """ - spec = TestSpec(source=get_unique_image_file()) - file = ImageCacheFile(spec, cachefile_backend=DummyAsyncCacheFileBackend()) - assert_file_is_falsy(file) + with get_unique_image_file() as source_file: + spec = TestSpec(source=source_file) + file = ImageCacheFile(spec, cachefile_backend=DummyAsyncCacheFileBackend()) + assert_file_is_falsy(file) def test_no_source_error(): @@ -68,13 +70,14 @@ def test_repr_does_not_send_existence_required(): # import here to apply mock from imagekit.cachefiles import ImageCacheFile - spec = TestSpec(source=get_unique_image_file()) - file = ImageCacheFile( - spec, - cachefile_backend=DummyAsyncCacheFileBackend() - ) - file.__repr__() - assert signal.send.called is False + with get_unique_image_file() as source_file: + spec = TestSpec(source=source_file) + file = ImageCacheFile( + spec, + cachefile_backend=DummyAsyncCacheFileBackend() + ) + file.__repr__() + assert signal.send.called is False def test_memcached_cache_key(): @@ -118,12 +121,13 @@ def test_lazyfile_stringification(): def test_generate_file_already_exists(caplog): - spec = TestSpec(source=get_unique_image_file()) - file_1 = ImageCacheFile(spec) - file_1._generate() - # generate another cache image with the same name - file_2 = ImageCacheFile(spec, name=file_1.name) - file_2._generate() + with get_unique_image_file() as source_file: + spec = TestSpec(source=source_file) + file_1 = ImageCacheFile(spec) + file_1._generate() + # generate another cache image with the same name + file_2 = ImageCacheFile(spec, name=file_1.name) + file_2._generate() assert len(caplog.records) == 1 storage, name, actual_name, cachefile_backend = caplog.records[0].args diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index 7b321232..72e5a81c 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -33,10 +33,10 @@ def test_no_io_on_bool(): perform IO operations. """ - file = get_image_cache_file() - bool(file) - assert not file.storage.exists.called - assert not file.storage.open.called + with get_image_cache_file() as file: + bool(file) + assert not file.storage.exists.called + assert not file.storage.open.called def test_no_io_on_url(): @@ -45,7 +45,7 @@ def test_no_io_on_url(): checked. """ - file = get_image_cache_file() - file.url - assert not file.storage.exists.called - assert not file.storage.open.called + with get_image_cache_file() as file: + file.url + assert not file.storage.exists.called + assert not file.storage.open.called diff --git a/tests/test_serialization.py b/tests/test_serialization.py index aa2bc120..a7755b20 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -36,13 +36,14 @@ def test_circular_ref(): def test_cachefiles(): clear_imagekit_cache() - spec = TestSpec(source=get_unique_image_file()) - file = ImageCacheFile(spec) - file.url - # remove link to file from spec source generator - # test __getstate__ of ImageCacheFile - file.generator.source = None - restored_file = pickleback(file) - assert file is not restored_file - # Assertion for #437 and #451 - assert file.storage is restored_file.storage + with get_unique_image_file() as source_file: + spec = TestSpec(source=source_file) + file = ImageCacheFile(spec) + file.url + # remove link to file from spec source generator + # test __getstate__ of ImageCacheFile + file.generator.source = None + restored_file = pickleback(file) + assert file is not restored_file + # Assertion for #437 and #451 + assert file.storage is restored_file.storage From 5d9b10dc18ea9c2f20662510de75b0b629a16d55 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 25 Sep 2025 21:24:03 +0300 Subject: [PATCH 524/527] Ignore coverage files and virtual environment --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7a5aeaa0..c4c4606e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ .tox .idea .vscode +.coverage +.coverage.* +.venv MANIFEST build dist From 67315df1d470267795b1aecf8d8ca13a10953724 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 12 Oct 2025 23:28:23 +0300 Subject: [PATCH 525/527] Add long description content type Explicitly set long_description_content_type to 'text/x-rst' --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index c31e0ab9..d1a499a9 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ def exec_file(filepath, globalz=None, localz=None): version=pkgmeta['__version__'], description='Automated image processing for Django models.', long_description=read(os.path.join(os.path.dirname(__file__), 'README.rst')), + long_description_content_type='text/x-rst', author='Matthew Tretter', author_email='m@tthewwithanm.com', maintainer='Venelin Stoykov', From 6f409c1a77c4c69432680b999fd8ae522f4abdb4 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 12 Oct 2025 23:29:01 +0300 Subject: [PATCH 526/527] No longer create universal wheels Universal wheels are for Python 2. Python 2 is not supported from version 5 of Django Imagekit --- setup.cfg | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 7c2b2874..af57bc0b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1 @@ [bdist_wheel] -universal = 1 \ No newline at end of file From 5a475ba5f398385ee4a9c824ce59f3a54fc9db93 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 12 Oct 2025 23:29:23 +0300 Subject: [PATCH 527/527] Bump to version 6.0.0 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index a38778cc..2617735f 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '5.0.0' +__version__ = '6.0.0' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__']

Q*ie`|Cj&2i?YTA`Sqeun>bF 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 z zo1c8f^C>Ss{_yROE@^#moyOKFtg6)GsWDU7h&a&fY~k9~>0(>IO7%9q&U_By>%K<1 zIDGg>V=9Kr-R+y{_Ev{{`tT>r_2uaeNnE?B4_?a4UwuVa|M;hW`rSYMv*+{E$M?^d z_fJ2(eR_U-x%L2oq=z{Zr69mrTU-CTzxmDI{M%pt`t^3qcKMeNk3U{rjdi+tef#A< z{Pfk&J{S3y{JxLn4%Rv4)5cr2`R*{M*B2$T#!zX7_wR9hqvTwU+1I2^JaNsAW_Izc zR1eWF!39yA$jjs|Ntvz5iFqo_DK+gPN$2?CJ3JN*I%w0%psKsY+?Wd{A{F)?v@kV7 zP;v?^;qlgGGVhIJWe)2oqzvX?Ahj9bw_sA}V8Q%k2TDW4*n-JxtP0Gsb2+;5~!g zI3i1(bdges8mkkLyH$xjl{r&l=909p#!N{FCa!6SI46$0ZE%Asi)ZfPEJ5izS3)PQ zM&Sw(shLKRlpIJ3PFB*MQ7FOW!wYd|mh=@Yl#FDT%CHb-_JBmriAXuZuAG`dfsOel zQW#0-kRZ%L7nMX7wks(zgD5EH%vI6Agc0Gyx~oeCKwBc#%qV3Hqf{r>5Z1+Gb=D5% zrkVwO}>5sgAu$>HV4!l$7V5(n$^}nPwYGdA8a@Cc&=e9aWM5lU;=@DMFOJ zXD!70Zo=TGBci|};XENB!h@(zoNG!`-8>tSQ?9N}#~5Pmw8XZ%`HuPgN8i5xw%z^& zC1Hn@C!#}UK7U*tmCWjaJZI%JD@)6#RXE+nImgv!8DZv!c8z`2(&}f2qq%Nd-}{Ev zKqvmb^L*H@muY!V>-&$FyVJ?&1^Hm^k=xVz>%+sNfS>&Tc{$xZ?p5J5MG+;o!{@Jc zKCz)(@HbWp5=B~;k9An@adk8OG*<)-NOr`y{wJljrO zBR0~*vA*bbafi{KP(`L_p^%%Knb#^Ww2ZttlGMv~-Y+ht;9WN=9!}kzo!bG|?(r93 zX;u5*e)ZGe{GWgE_1Dw!3_V zNrHH;@IrDa<>=SQ=ikyt5S9Z*Y0M&0CZj7Txt_dqbWm}Rs#DK0BL&J7fNFB#(Zc~% zt{#*b$wF8ynTRSSCpjcVDl);uq8T6rjhTdj)QHiUK|!hwo=>>Fqfh(1_H~+4doz?X zBnIicrx{REo%3>j0?#Q|2^Pr5$MO03Lv2T#G}Iz0Dvk3rwjW%eg`d-ARP;fKUBQN0 zxt83M#@Gv~b8F!?NT#`P)G}Sqy}(I1&J^AwlvKbbn0&il&)c@|XoA0x03o(@6Q&*9 znM$E#nW;a=ihxSelx$O3h-4~Y=;_s6ouw{V#yMo_(TT_{fjEfc&}uNMsu$VExbU^x;dNe~x=tl_qJxxmY)8#4v57ABylF#%dPH^iQt8p7R_wvzb zo;;XJN#2D9EOQi_k>|5(BY#F!-AV1!)O*?8do!lEKJCytS!YqHjFEjqYfTXV#mdUp z;gzUu8wqW`%W?K=x_h#(Tq<}BUzm62xLJ6;c2d$It>x|k76As6l9^-lTF5Y%L@2V8 zRcV{+qT}VSTL1Ca<<0PW$WoFIRtu z%h|6Z-FKzs=H~g~Z8|?ZonQR&YEJ`vnW$x^YuVl5R*r4&2{=OfU;TW#YoFF{KR$lDuPfF2xqkk|%dd{hm&evVjJJ;tgE&!9ua&QJYdc~aOVsh> zemFcooTkBfQ(|j_D29VZ7Jhi|ep?U0>(-;m(lDCbY*u#dgLp!?h{8IhD6b+ySB!7| ziQaB}I=1TVG?AOPpowUd5D33R`4ZzfyK^}tCrC0O&Urjx?N*+s93|97{4EIrbxJ=Ce z>R<);ZnC7W9?T;%OHYSEl3+b4BPx1lr7WdLTJ1bQ0v|+3Ds$#Wup||yBncLRXOu|i zCVnLm4tHjRo@9FfDJmf&i!-1JmzuO?E*U$bWP;Ub&zvT+tN7$Jh%DIH#A7d#6m!@X zWuov*giVY!by6u2UH&g${Vj~hyBy}S?>oe24u?sRaZWiP)Kp4%Pv`Cw(sNG|8pa44 zkz)f9h4pSqnMI2fJ)K$x7m^}OoCMZMNW=prBS0){=a5;dq!GE16l$DQxKrd#e#>$p z;Sfm-@9JLl`4YVkldim5?$WN;bS57oO978O-jINim=~ER2E}g7EH)wpMbwN6Q9=-1NTpDYUAU3E6VUn|1O_V|>G<_O-v8^{ z?c3kQ6^)T9VTvZ`MhIzzO?&JiFv}RbK@2JgXg%Ctj=y*#^XE{{tl9Ucx0g@<~cDZ^Cnr1b#u!o2951&5$FzCdHK}b|*J4f0o<$)9?SKiew@O;x9n3kzgmG%v74H zes;6`>;LhWfBQF|zgo`gKfnLjm6_<8P7E(dWFrA3Nf8p1xw3%Q zZTtRT=#OWaZjLodLh48&P;y*S3eZTBv{Su-Z^}wi5Q9=PAB700InFsMO$|t7BXUkn z@6aG9cV!^ULI2}%Di70&CI_*1u`1bAFruk-ntSqG8ItBg!qN!tLZOU(_-Z>*1V?vK;%vlSMJO_BEdnXX z^#T*WBs&k4b1uMsuLsgkV z!Je66qB6|q7^Xbn5(S(bK|m)~{6$j2xhB%tiHMW;)JEhy21P)eeJ~nfM^v5~*%_?x z0GvtoJF8}k-f1{b9H78DOlG)a0v!Y9dI|-qvZkJ?XPEU{0G!3XFht-3O zUaItn)ZOxMkG@)w1`SSDQ~i{keKQ|B6$BBt!*yQ~Ot`kPoNn%< z)am&0`surNoId~THy{7}+s(XEk==sUmw)|B@#)iV|Jzf)mIALxC-rrYiG;#I+(h`Z z)AaBD-9P;1-@W{j*8PwDhqvp~nVIZ#_u}-c-yD81S6uSrx6#{fMvxRDQV4fCTwE`k z>NMTITyL5y*OmIn>2NpI#j=!SN;zri)i_5VTZBj0k$DrMWTYx+Xkq3;rE)*p_P{^> zz#pZ}G~K;a>MSLuBQvOw>phVWHq<+k24S$sex`$hC-E&yAy3oi-rBMv>Dba%( zr!z_DOzMy%R#JsCr6DDSi3_<&BncDE+%K6u49tC4p~3m^G`11GZpN1(9^?6$FT_zK z3xOk(n6h6J398zr8LO}R<7dD5`NTpwM5}iulDZoeDOR@i?wQNa^ieh>%5eC zO2^2J+=VrRlCzLd2^s1_oFdGrNu@}EZ&unABI>rMLKdRv;OL2PcO$7y)19k83_2gO zm%Tr&&P64iyYy47H;3i^i+MgAZ;ks8NuF%aG@H(%$5vL!c19-)zZ_VLDIa| z+>?-F&q5I?kzn-_DGQ=!9Le3a!nW87kW|>gG`5TbWY1t0LL~ko9lUrsldJnAHnNCv zjVO{B0?Nwfp4y5rm&&Eq3OVn%Y#dtv+5+p9BXb{q*{r~NW_m)k1d$?!OVjlkG~9g% zqdz5tsz$d+0mLcf{20L*9nws8N|mUg9a54<7-?KGRwhXkCU7Cr5yKKeNd!qR)D24T z%>b^~EXwfQ_p2Z(_Td~%*S#PKRofiH*Dj@EQraQeMGP)MG=jPakBw(c|M(AI{hM?9^Z)wvANzBt zOXjrr*b2x+#9RaxAh~9nv|u5ZDg`E-?Jzg^$A>)s;XB*jWtkE^(7Mxb9T!&(EVH>5 zvd2+oUzejhD7LV{y!(9j;&fYI`gz`d*yw&cTlTni2-=aS`7j?ofBo67KL7mJpTEAJ zKL6tI^0s_2tMeAmpJaVrAN^^whjD$+`rQ-#;k$?b&xh;t+Cw;jLz#pNv0CA?U$`=J zVdBiL(5V%IUdPtg>%M{`yKgwQx=d714qB#mTg$e4-?8tx?iUHby9RQM?(^lLKdom` zT9&)t{KLQf$>%>mym+y+Iv?ke!;>F>`19kZPkGbYtD9kQUV9i{N561mHPn`+l|@gL z|KZ>K>KFfb|CRRfxPCle#wa>-`}}nG4__}|-^;X)cTYi|MRArn8r#@YnZS0Kl{*WB z_9f_4{ZK!=hQF-OnS0ul;}X1-qn2b>2`ijC$t-nCD$WI>8AzH`67c}>^?asp&v=AT zooW@boR+9WK)Qox-HilH6PJpTEW}2x2VRM?Co{r>8VyDmXi9U$hD_)+6<`BqPv`Q? zFcKkQWKS`#O9&&A4Z-ksN}WL?%0#qqgkWxxoSPm_2kA;uZ182TAyvoWz)j!~8;)c$ zXUgl|FP|RAzAxqQ_Q&h`!&_wOE^F@Dsz@!^YHQQP04`5Y*XKv7zJ;YVvvvLSBJx7ueXj^x`8a-QfxOpgvZLup>5E^)mNJ<}( zo&uRw&Ez;ZBaGb0cV%V$LLg)`sm#N?gK=SYe(j zD7Kvs_rd|^U<|akJyPLAX}ErX-iwIRu>6L z!IpzMoKT__7rF?^G(jZl6o!~N&0$=$P#B@c+2?-(}67)ab#=A8$Ew2 ztD3fNWA8SB6t$1QW@&{>vz<=M&Ew;Fnp=c3Ja>;W=P=|}idK?t`}yOi2%p46{N>O7 zx|Tk_dbvz9ybCwm%EPzcP{!%?jVhaExI2*(4NT|jVDj5j{kQ-9um0}ee*X0r+jx6j ze+b)RhTqTa^-sU5U%!y~BmMX`TJf7I_Nyd@y9U9P3Ya*@@{SW^BiNQP2q)HGPpG20-nhu z3quM`$3!QR1mz^zreP!5lN<3Z7mGTjO0p9;t*0tVp{xQSHcmlr5#Wp@iBN{JBoibh z38c*Fgn$uQ!i}ILN{vyNW~VlBsS|Q2lE94l>B=4$dk!~?0T~peZD$^Y`E;b()(@Ye zo|=LN#GlhQQt&a3)6`hqlT8Nk^kR;MH7h2`Nt3q}31JF?jdaPqTMVdX#v%7IM8-l`sDS_n%W(@DV`5D)Ba zwg6*@LYLa6S}YT1p94HO3v>cX0(t;9P8`SqnSxmSfsUVt& zi$md{%0!ti~c=D3r za-f|9_17XB+=Nh4T+?SODC8cF(XpTzL{NPx;t8> zsjxA5dbFlVk!%C=X-XBCGm^xEJtZB*14Ngi;-H2YL0y6HR>g*gNON=5^saz+M7Xv( ziG!GwC*JPrSpU=I$KUn$QH@+O%Pi~ed*2YrLTWp>MiuAE5s^s&N{a}M9mC22x{h}b zasH2Q{roLdr5*9bm$Hm~L+HZSYB<@4e0aR2(|h)rebOy|ofKRs|8 zc6`H4hzhNbd<~6(?$2k6>pENtx_v@7uo4r(3<5bLQB?ePn-T0SWJyb243?E+`$zC^FT;VbAMI z%uT=~Wj?t^ky{_M@oU;n(#i672RrPZnOM)LxMParv= z9dbODn>pJJ;R3N9H9tK2bm>Y2r2Z@pv4q-OTGxeFcWCXep?V1dg)LR%4 z0!EYo4NnFeX(l6*nL3m+lMP9MbizhF0TG6z6%^hMm=zO4PE?h00v|X%n$()4^>8RG zfV=iEV9P!%oFq5Hz6Gzm&~bk8%{Pxq8y|0}H8V{o8@oSlJUkG`;~`1HU2i|1PxD5> zDatI)Jc8*!rG-0HO>NNtPA8`|lcy0@2Doo^H3C{~=Mk~zUPVnpOzX6VA%;jv+q_fk z9grAs;t{G7x6|=h>+Rjt7Mg3DMwg|4F3?3s7auydxp?8~m9%EoiM*u`PIi(ayTCiM zvp|JN3lniqUXn7}n;b*9f~vV7H=hcam3Tnnav>jdc$tIPj1Nht$DuO~Ydy(! zr>r2LSQJE1f&l0aU=gG{gPEM1TWpa$XfKva<}IbA3UvmyprjxYBnkD6IYBgNiUjL9 zybv<1J6RIjRX~!q0VzY||NfhQCCom8k`rJKHsofJsgz*HB}v7w&j@VcFouU0LS!O) z1XnQ(j#{<0dBR=_YYizXWl%sGBe_fyk|hzPOLBU!G7F{b#Es$6w`>QojleM{@5t6T zg9i|vmkyqsHg*JLM~=hIc3peO*m9t486~o5l~TwNS`-@86o|+WZI%0;wQ%F0EXtW- zUQ3G&odli@{w$e0k?*9_*v2qbfki?nMpDuMl&J+3rm37KmG2z z4-c2?$B*k88nssU47$0!Kfiz2saPa48kg~O?$}?xeqHZhefs8Kp4Y*JxHTX9bh^=` z=l#>=!xal^a+~JuecJx;V0fd zIv?p`-~aCSb*WMhG##5Bj;EV6ee=_wzxsz?NW(JSpMU)0zV<=n3D)JP_=n&8;qqa<%gfU^es=oo_3hujtgjAo{sE6?X^Pty7-uh&kEX(0wp?CH9YJ*s zxvUDwWo}AW&cRxgUBTLBotIQ?RekGm9@x)8Op^+)AaOI>ldMLK_WZG)d$Fjq5F58b zR7fU>qfMbqQbC+1LQkS6sDT#_PpT~R7o1E&@Eyz~oPHr;0z(+qSp))NN+y93lxgH( zsx9pb77hgrLV!|mW@iA|BAq!oIMZn79QzoSnH3b#$ zLcAN5HWkU!;T5g%+&}&DuYY#BJ$UyLXFt4o{O-H;-9t8h{4~V(Jt|w;<)Pf&9xX$7 z5*AhKBiR$I1f_x)I)defNvK(sqvU3#YS?JauWL*VmPxb^D~m=4Y9YjAmbDNd(z;~d zX(R@5;nK9s%&$IwbGzv2)qHc{QbZ^dEyg8MI8vB$x+@hbsZ*8GnNqo?qHNck<{VTL z2oSD;BxHK1Z-Wc>vq%hLvNc(WC2hEAVA_2rDV)v6BT)gbX#)&rNO~utjy}M?Cy_f* zsEzJJQ-f^>4u(up&P-8)B_G2t1Te@6l51KfuK=fSEFesj7kDGvjGHnRsvQh|c!^XCgg9i`g z`PFBvjr#CwMuPX0eS|T@;0}thJvi5dOP`S>nQ2C`k{<#W=a%hA`jl9r?67oIMo{i! zZV8H3BdzQn9$DQT_QQv%X6_xrBUWLSrD9=HBGGUP4+(e9Jho#MgR2%e5N>%L?rEUa z1JxPsg7Xk`PIj&>-OB+YX_2U9DhMtlD7CSRRPHFLA?-U+Yx4xL()GRWASSzuNi)j@s6GS7$*L)y$}pgqS?E zxosL{zU9h2Ho|(XeLdb6{^?7ZUfE6sqx#O%VYBu6;FtGrcPH$tS#CByY~zPVe|yP~ z;j6p%wH}w3KmVDJ(GdtwTC2{RS(hT^xUH*@*V|huO_#$om7Ck!R^{pW>G6HH^hBen zlFIHx%%pANf_=1$x8p4%k=80tx2H)5Q_MW|?Rt3}*N@xIeNExNjf-%g5)3=X639)%yv5`^Eh)|JC8E7dNFoJ^c%| z6{_bxzdF|K=C58&FOK^3XMFR_ML8@{!k3co_)fA3l^b5)hE~XA>jRf6I@YHZIs4{$ zrD1hvg$hY1Vf2T6Tf@BDBw$$)J#p!L-4Q}1mv7!JAKp)3UG9=O^gf+gh3Sketmyz* z(74dNV|opC>`u961lh*!Oayjt3HAVGa(2!^aA#~(TQWd^5Xc}&uoy;dCU6zii%zb!ia*np$U}pVja*oY(NX<*zx?6H^Z6VwH-y+Aq2-W1a)=*_%+nrD zdR=0a5wTvR2*w6g=I)haA2~*L=i$EYleU5o%fXEzEHW`_)|AM-i(~Jb?G_vp_S2i& zdUq;^6Hk%>i7i5Q@17pZZK0JRDM7r)irm%uko0Uv&YfwT(6Oul1bTTi6W-#F11vC$Ks#L<%Do zsi$S{OeAc*2{WRw(8v)kla>i+Oby_OZQItJLVSA~fsSIq#@J`gBAt}}qOt89Y8j(? zGBPE?35}8v3|4YaS?X}2%}|82@!mxWbV|Dnu32V8Z#*PRTplw#wI&HDmEkhGEA3k# zDo|nNYzQnd~QR@c!^zp+t=fN*t%IO$BY3S*0dinCz{ru+X z;oWtNq!6Wby;7}4mVxbJeUF>tXH%O#d-3w~moM)>|FU1UZM#MgL?+QD$IG|xAxWiB zAI2I}*^T4jfuSHN9JhxzV>XYDN*uyMmgV8;ZE{Un9zJ~+T9%2%vu*qJ-M4@G{cr!5 zfBF6Y>$iXU-+%wl|BvnYlMGxx6_F`Ph+1?1*{hd-_wT>@>5H2echmEquwJeY>w+D0 zQ`+DEV|y|1{Ea=VV?I%G@*&!q_0IWq;iA?JQ(_@Zi5{Et;TEIQ*p1X^GG?x$QiE0x z_sD%4c@%gSyI{)x(amaKh!dxvvYwJ-o=SDJRA&V?jsLiA^ypld6 zh4sjtKn(V%l9Z{*;;Az@QyEgh3Km#81;GJ@3#=qhLBiTtKp^G?4&q2jvWcV<0SdU{ zFDQr;#30y0UYgbfm0(q_6U7N3jc3Hmgi+IE0+LclQv{`zB+^o3Vn`VaWS&SBNwu`8<%?IxyEpUP>MhG5SB8xI z3v{g$lc*+$i?fEdgNFt$A>?ELoJYz@_j4|uEmAvbFl*LJs&WIWq`*{3Ea4`5t!B%i zsY#?x(8_^i9v$jCz#M@gR7i}487>FU9^et;iav^uOI)|ua_n0`hd1AMqR~@rs2P(Q z5}6=g$tsOde?mv}C36o0qJw;-W&yZIm}L+;s*;}>Tb7oR8IiGrn+=u!>({@@2xKTZ z928m1Vz?8PR8LOMC^dC>)>yaD;&7}E%}i#G5coCW>C9T^qONj~nT2SYYU&Wov?wJ+ zX4am}sVz&_-jN8Zqzsyvb_f%kVsRMnL1iUs+#jP(W4~fIW9ME1VbAA%>sPDY!?w|f zZv!=`vjHSMA;JenZEQ)Exi#)#k;$ZC$3orK@2a%RI>-Oz_-F2 zkugu$I<%s|iNY+Ii!hnbi_mAch65g+21Q~5k$C56vPDUf#vWQ4x#S(_$E z4L*(Yb@ZsyZfpJY{`nf+3eM;Kn{OU|`~GTrSl8~6bDQ6M{hQm@_f(GSWE@}JAD5{eUhtgfr>j`*cAfNC)K7Oe z*QaYZjj^ZNvEJX^-aS2iZ@qDvGpF~Km6vhzlb_0d{PQ3G6A06BDwz6M-+%Mr@p^r_ znyuN-AE%R?KL3rKQ}da zcPt7i_ZWs-|+t`%|$Ak2b?diGgyYh|l#*2W2qGxHM!m^W|NS&qSV2HCRCgn?_ zKIdsBQrL5r15pr9JS=IaF}Tj)V7sCmC_U2{3@z{k?GcJ}ApwMWcqHd$EE37YAsOie zAp}x@LIEO6C}BiIc7+4|n!ClmJEvvaFXz2m7TNZ=1O`N^fS5$IkV+e47mk~D-=Cg@ z;wS&=m#t=rVLJKw`NJQ-lUHxfAD-VouMu2T2~3=-Aykl#!7eGnl(N%MChI#Wp#_8> zAtB#vgWcZTZhMF7yxi{V>cSJXO*ajU;E6hEWg-$FJkD-|9YbU)O{alZua{RZZV$(H zvyha=(am@d^li{?QW-_cVIg*|gr)^oN>N$YzNiE+k_f5nm6(_i)6A;}qM#Y2NT4$3 zL^P^WiiR_liQ&Q86civmkQ-{-jp0|+C8Rb}5sOH$cCez+QeFZeb z6T}ph6(utR+8E&@vL<F(dh*T|7!61P;Yjx?CE66rDf?bABNMsSpYzKCb z6euSbYA2##5?>BcGV-k9u&2lgYC!-GB9VClHpJ>7*f$=an%I0GEfjT95{N6IASt0B zj_ zjGdS?hxCwjM+qYIZU#JBz1^SW#B`izR#cssMbvky-Rl`t77pYHsm$HO{HhTZ=510L$KIZp7{Cg0Qpwcx6)u9qo#Q^Oc zehw_?J4tem$Sp@B1G!UxN@L#xnKUOrlB5Be8Odp25cddU<=~lx6AnbC&_D))XDS8> z6bUXYMWP6^OhE|;l8EM69oRS2X+BQ1NGqjbs#U8TGMT#OzGios?;?7JEz{w_w(a=` z1}DcqmQudhj(T8ZX4UKnoF(0ApqLRVd!i@%FL&kjI>Z#`17+1A%=~CY7@7o zkI&R|zg(~H-*OesY2}qWnRAY9c#}rNk%mZdrmO8rGr40MGK0Y~m17;Xg7Z^`S0VXE;lqdDx()ySp$on7B$2uR>F_!n}wu4OJqJ zPR!ssOcXnh3l}BNLtUqwIoBe4U<5}foC)qdSShcq2whh>*c@ZP5Ifr5eapgbu{*iv z7s;=SN5SBo4&Lz*XU!#xoG0ccor_B9K+{4cDAAa_0 zxchR~&6vAHn$$R7cU3uY4i!?SEuFBubnA%WRe5ZdN_(d&xppLsTNPySdC_{?G}>If zNGG1Sfi;B*%#>YdhZA5-7Yc$dX=e4rI}=w4qf7*|102|mcnaT`%1EJMLYjWP%E_Ou z>v~x`nc;a04l+u>3RR&YoLEHMS~7qnO535e_nd=Y=tveSLE`kl|^U&1G_S<*ow^y5sjgp?-hR)^18)^EIw`X&0yGM?!Z)Ed< zN?a*~IHiE-@ciTV*Y}sT_isMze|m})?$dI6_gUYz=jR8Q$+Fq?liqzX<@o*&-ywwA z)5qb(sTHy7J~$QZ7O`)ATwcDq8(XexJYJt=dc$$PKiuEE_-sFac>4YmrH`E#o#D08nJl%fb@A`Ir`>+4%&CmYs)i1wT=+mdC?=I`p1?3>QwaEu03se;%bX&-U#V$AMH_K&%ftcLKqBcm7kDRTWF{%B zFoHOU=WtN*q$A28Oi3H3A*YnVWlCGqch-e+BnkN-;vi)gn1wXX9ULS}0>qhF2%U6- zfhmy;I0y*`T6lOycEe?h-qG#)bPk7^uOl|n4c@oxGOEh3Bw`y|%SyQ&U)|r|y!r9{ z4`04K-hTFib4=tG`0!8vobB~D-@i4=BwZ$o4bM+2R7ojlXha@Wu7i#f`PSx%c*z_p zOIV-@YXvKO^sA|&OUYW<&GuDG^TO3VDY;d)o=#-$A#T{Bdp3BVYI${gy8rCO-NMVU zAdRLe9E#OCK`P}A&rtpkg6*QwdBH$M`ls% zp2$#J1P0B>M3lpfiqDI2CqXjWw64lA5w!kh^DMm=|kTY_OkG!T`xgeZe~nyo{Evw?QcXapl!B0Q6mgrY|al0$k(2yxFW%8>utum2S> z4)QMJ91TJ1 zW!pUhyX1sK&(?7gt}8C zGAW`^Sk{7#WP*DQ3Pg$uDJ)gk%hJ8@#AlbrZ0j!Js>rTfDVarB`ZZPHT}7cm=`u|c z7MwyF8d`|kv8ZM7E%vc#|1lpw4j(z`*kqA`yBjGBr-jWgp$8j#k+R?abmQe}bw_#b zZ5_7t>3se4@zeVLig!=@4 zaXXdUyPx;Vd)r5y58|}jp5|LzV~o4cf4;u|*t2E-aC3M6*%x0FV!J+H;<8^m+}(Pu zGF-J{+j}Haj`?PK@%pRhAKpGaf4I5-^5v_$hYxSZa4q%e{6wtlzP>p9)O}lSZ*E@y z?BT=Pr>A|(F4O`!QVJ`9UcS8J-M_fI`|_*&>tEhZ_3iqtK0dACMQ5R#*RTHer-FCo z`Fkoehs1u#Nx~ZOnWj7FPVJDfvrQJj+$gtnxHlc)wyobkk(9gFuWLnJ4AYXvwm!yr z&8_dds}uG$TngLi@jKmGjmQG-NU23iR&k2R8`4lsFo-JrDMC0kRe&T+%o=IZj>KSE z5L?cLbOM}7;Y@AMI58Y50w-=hEaWJDO&87)QWH*OlpIKKmB^$5PH-WQ)I!vm2?PWs z457?K(ZQL)5uGkqw-J|N-F&z8y4ry$>tMcyZbS|peH0adozfx>%sJ)D+c($8=i4c6 ze)hGNNyL0FpT7IUr}yLB_jAwJFOTB9#|V`A;((FpqqfP@m`H{pl8WoK%XCohM9Cz8 zQHrOfDje&zXCx9jX{MHlL0(HKwIqSqBDnuWLZWDuLp$ETobSK9dG+Q^J?OD+7~~QW25oGs?8a1z&{#Vy2N^poU_(@QLQbG;kvuz zbS!I3zPe&eq`Yo2)!aH!lR~94Xf@&#@#`uQttu>-jg!618KZ`;DP*9OAn=ydq^t<{ zY{fjyCF+JvR6N4Hsp^z4-C;#VhK+!tM4u0>nAx%(d(O;`Z+TG`)NKXJ5y~T~j-@Lp|1I?t9m| z@HGg}FF*Tt)9wEF$@2DiXg8Pbdt~koeuz)~VQTLWw|6L)?)Jsc|8|*5|M=t6<Nq*@ZE++mRj|JR-$er`pOsw&--(e%x^bV_K#$&M+Bd%XHJGd0!)Gz4`Lx>mPsq z&7b~-WPlp&gMjtv^8R;!cszYk+y0CH@$X*QpO*UZ`aAl#^5r_FInG!Wb>u`+2-|VUP*{!~1FC3C?4M1`qby&2W~)bYFuP@QAKQ;{#=46z z(z_3qDs44y} z6a{6DL>hPr9-KyPD${k8pb|VY`l&^~s5Osb&f#vXBIusj8`y}95kyqt_IAD$<+7>F zNk)f5))z*XgG}Gy0?aYY_mQsl>EUKB`|X`z)h)pu$^dylhQGp-U2O!FG^-PoWc0z6 z4}vpn8>@6-CMMy`b%bPDV(}aAXILj@k;P%yosvUYrJi0L=Aw5m?o0JLld;a$dj^Jp z)#*?VCZz_iqBG^7S~V<2BoZt+Qg8_>#JleidQ7?yvXH8sy)2wFiFM<$2Z~E6K^d8v z9#SHV3Ui1gl2=~E>u?+hPb``+V9-UU+Zp{TC=*S&e`IazFeR!bsf*YZ#5`BeiXsv{ z$|SZTE)dB`L-AnGO3UfswH>IQIApP*taAAjkMZ) zOszB?vMjuW@fuZ0W|B2ffkgz!2cnt%N_C2IfCN&Y35=YV+Am4Q=-Qtn2dPHv;X4Wm znD(L9i%wA1PyxX=8SATv$jkRh1H#Zp={%sP?gS6&Db*iY8@(N;}aQ(M0AL zMHwV;iQ+0XXKLN@nNOQ6!%useVhx9$uW4g? z7}HZfZaj59j%ySxhgZEG-#=Z>|NO1|@Tvco|MdRy@v$6n9o!%HDtS1yQYBILz45xH z9xnFsZ1HxRHc;>&1tsuDsnime z4bpF4y?OD~i}(NS|GQnU{jx?}3(cwt#)QL*z`gDV$N9AACriBHcL16>}k&!0X_r*>*D=CTy!Q@g2Fe)!?fv2C}n z{;Ga{JlrjZdV(qS&Ed==xo+3}o8SH?t!VP++sU7P`|;Bg_NPxpntbtP`@6ro|CN>f zVLx+N%>+kAK_&){L&>Z}kK7{V$|)%eD7-ZAXo&+bAC{xW@u)SgQY7o*kB{;FV{Wc) z$YhdA*S5ypc2NW`_c}M4D%Zi`8JQ608g<6TQ74R!sltrGES^+^Um_LoER9G>2U(4n zSe?2WSN1(UGA&ay)+A3ZWKP{_JyVY4jmJo{*fRx@TZHm}J0T+-85cN3L?W4c{zZ7A z1S(}FM*3mwk$%q7Xuc&0ZH?MOff{{mdy7zSGdnRiTm5=9-$`h2ZDO3dzkl${N@w4H zc-}u=(}#`DbF$J_b%V$vi6B<$&fo8GJ60KOY=-*7QF%xw4px@aT=HeYwiTlj8M+!g@Fc!%kN!ec&LC~1#?$W*vs&Iy&36cVm#i@GpF;x$!jR@OSwkjj4G~8Ia0dVkYRar32)^1-ltbAn zae%`VZ8O?s!K)$dsFo37q_HsXauVI{Q=i6^Qn~TV=d!(4-%m8{<9vAh54XSnV?f@W zEBO9PZI^&~xVfw+R||^b$h|pGI_u5pmL6ArY%i*e8W8=6z7DBxrBB;*IhNg2*-RCI z?eg;Zc(LicRxl-?giSj{0dyjqcGu(ciFwGWoIiYXo~?D-4_EGV_2NaIc9)y$l6TG{ z#wbayfA~ur-R%CucYj>x8B3X;4&7tvCs+dzqgHo@1vQ?A%`~Mg!CajT#5KIb{-cjy ze*B4%zj*n@{`t%5Yt{Swd^djl>BG0b`S#oY6*oj_s;G$Q9Ew`D>E-jw3-;3=AK!ep zeE;qE=KJH?>;C17&1awQFExGm3h&PZ;4-;!$3d}>NwDj(*LpNfju{Lgizo2eqMK`K zQISb(PM4d@mnm(wn58fMe6EWQVZe^0p61gq+tdw7Id7y8Wg~U=jwMsxMq80CSOChF zyMyn-Pd*HwN*EAm(Ev0kIV=b(cn(L@CvQe>KrK>n6$GR>Iqe85Y6~ys6)XS=s(Bg! zEYb+-qC$qqgbZ$E=1vn}7!HJJFak(mLLjsV0|G{Oh%>~*l5yK;oFFIGRX7~;21&LV zbfyI4ZZv?9CZx!YZHcH65KS?iI0DwTnzJGf6oeCQ_m~kK>9H=@4Y@-pn`f7KNCmlD zO=Xi3o|X=jdB_-jttOIb3Iw;h#!65G(411FN~^CYXl)&N^5-Q9T79uDY zh|CfM3*k-)0xJ{tTp$c3TcQA9cY+02A$1aW6hO*Ap*0LRt$-lOp;k_%ry=DYVvd+t zhk%NmQbuhM+PDZ*Mv#;UoHH@>aMlhHqx)HLa0nZ+rLrHGNO_5I!4&EB> zdo<`4oY_in5F=tC_F$tx4rD~P!HpB4L-lM6RyWSVn|N432thisb0R`UMi69_fdNT7 zrO?bttp!^5z!tC>A?*k|0LHYjA;aJr7vSeEGb)94bAUiZ5D)~#Rya-&FTy88P%UAk z$pQe=#;gL6F@<-Di0XOi)H<{tNPQ|v7^-82gbDL zxkPaIy27f&UYnMVKrDph8r55EB1l;xBP3!3Hq+ohUlBc#kh%!ES?}o4P|+O`hwt@U%vSCpIoj# z`!ZdBGJN{O*bLbRTh^tfm9A@g^@!Ks`?&0r?~L=I`1{gsFW>&hm-_WSmK~fX$JE=? znUKdkY+nBO$J6$*KOEK$U}}wngGo{;A$c4IRNh}*E%SW$^|x!Qz!%eIyPl4&w7a|- z#?8&EKT>%3_J97jZ@+(Nra8%!_AWV1+wHXd;^yXy zzr4J7^%AIl^Y+8*)1j8#ba_2}{?X-6Zm`eoVO8JwW1q^J;3Co(usPjXFt@ zWME+_ksVP|L}n2hX?w-f#Yma3FLZim3Xv^v32y0lJ1v$p@sx4e;51+bURIOha)E#d zr-jDzyu`5Wk=$e3>^`bB?Sn1 zBA=@WoV|>x839E$7X>CU>V%9=Z0HX2=`jVJXF7iOjv{-jJO~drP$d$TapGZ{Ho&l* z5`jS(Vz{`XVW8A$C}l4R%-xF-^d6i*xl8h#HH><7GRP7^9HCB-$dGzWW<5xOL@4S3 zFq5((Q?CcieOqXAy~)Wir&1PBmrhQP+Lc$dXe|RI;Yy;3hD?f^hBM-F?3BPL=b?93^D)_1S2M((Pd8ph#M?94H68AM5!wxNptkE z9T_5EB33sN&zS*wb-C0)vH)}N3d$Z7%dz{WB}HON4P@8Z!wf=FcWlRq0bsH}69{y7 z@Rg%E*ow3fQj{t6CnO6cvIN*2C2&t>$t(e)%}vRXl2deuHoSo7Eu0d?>Y$p`Dcl@^ zEko_+Lo_#CDB0RmWk^9{QNTUAtLFypV2OMU!W6#ezPMTRy+ew;brlG67w2qIQ8Zuz zU(qXQ0B?aYJQG-iPz2xv5tg@_m{^P`6{3_31lMM*bq0*kz}lNPwzZAIniHNiC&3_N zVyAFm7Gr5NC}46YKoItow4`bkns)}0)C%!5RUiui2Mjfe?nqoEC|d*2Iu0n#XpvK| zmaJBgxkEG34q7;p2S`Yk@JK1TBXSrdhXC`XvTH0|#!@~%9e(m<`uyhQUwrY=^YN3L z@t1P`>2SX=Vm-wy&z{P~14&FwI8V#%R3C@a{pRpghD14JIrj>O z+q>U?yM9<)$2?tML(^fmQB+9TJ$I^%Daodvo^U8$bo=b{LCWFj_Bhv6WV_ooeV7-u zI&a2tb90lX^vUNRef*<;Fzx;D?cc_0&<& z{O;R(&jQxipe6{y{i_$mQ`Gu&f9CA_k3N6?qaXj~pZ$05KOCx6_A+g5%Cw~rUmriY zNgo(u5=JFA zmIxjaI1c-80?NHeLZZCXh4hXMB{3)TO-4y|5S+@nd-v?zcpL(tpy!JW-nVKjx)}#Y zGz|m}&KbIMvJ*91Ic+$RgRcOx%XZSfE@*&AJfvQ+9V^ZYVY49*FD|VMkftFIlpM&3 z-F*c_ps*AUn`zqbc6q~0;sGNrBn}enD{Jn7XIBCkhg~rv>cJAUnwDq?VMsfMimo&! z)(K64Mn4fQZ_snom5?kZLuBj-2*AqC^MKVI83EkU$-yv85_O~uWU)4-0jYKf(qRZg z$xM_XsX|}{+-NRnJ({UfhDUalfg+QKM|f~y2}2}g=h1o#Z!8-~k;oASP@;%nV`1+} z)z7^xG1gw{EZVzv18t#Xx3%H8VYTgzgS0T9|QmcjE-) z0Bd+xa^g_$A!#BSoy9N*I3Y9|6HW=53dJyDC1S-+-$Lkx+nlK4fsIz2gE_4XLpk0tJ%-Vh=W`W||A5;o1jv zaf&G8C>=&~jUfl3se%Kq)femD1xY~-t)~G*gRs^POiBrY#yDU5;iF%Spa0eN+4B!C zH;=mx@cOj7fA^6-d_29|e{qq9v1>i@^GBDb<1sRB<+yKsH@_YFF%x1cC2=U6SA2Xr z{{5TN+ZvsGls%~eLIrA1=e9mrGSLKK2#SorKqME>Uf!KvL!i&Mt=R~Ees`aEb8)R>M{T zu%<9S;+Va-D4foBsx86!N6)TrcHV#U zjo-rvbhDS2zxeF>uYQp5Xiv9*i8hk~=54^lF2;7+Y{N4kyQM2#_d) z5px)-mOV`q0Kz;|>B-i9_lNd}U)6vAeY`!|Y4#P`^3YE!*y_!|J!S(VfF6_}&?#aV znHno&4oDLP0yC&5hzNuNRFG3ALlFqt8CJpxN+zojrhW{TSP8Xb1Uo_pR09P7K~*Ml z%GggB1dS<{h=#oru0R~o$gA`@qD6qakpuVwp-2+o76bH9<7lgcLnIg&K}oVf0!Rw5 z*!0l3%MhXCSU9p9Ihtz#Lw`D``+9ru$7Oz8<{`(@Ju)ODz_c0bLH9TLG8b2e%xOD? z#P-Fu5y&v6>#R?0zJ2PwCG)%iUcqU}r8pXP_0}Uom;f=1l8fD)t*^ty&b>nBwBG>+ zO>If-?aCEwK)kR0De##DKOcbgT;ADH)ZF3}h8_WmjUNZ6KZjcG5Yp z_6Q^rG31`6fvHH$WZH&FV{3eh1TmDgYT#%&v9HA5K}sk&37nDl4#evdb?D~Z11Kf7 zt^km$wTNQQwV!J*G;s8Vy7x94b(P#GV>t9iYiDz@7633#QCnx0$N|0Mb|28(0>WS# zh%gX=040PG$UR@cdIm;p3o{5thkf{>c}zandDU%BXrUmqqKm^K53j%a_mw}Uby$xOS5nlPUTUnH*k6RDxx8qUf_>Cwz@zk@0s6AmXp>BIk(bkO zr>8%?US7}OC}Y__`}l`T`(3_yfy=|=hxcGS+OSHOaV)5<_rR9&_3`w5eKPNB8ZTf| z%vLW&oW}4nO#7Qp%BYLpAO84sembHI^Sj@#jD9+M4c7*Pa1FpfL&GPEl11!%$eVom z{POtvPwuSEL6i_cc2e;8;ZZrNBE&N6pKbS-@BY{SsEMYs8@A8p^>K!Im{X-Qmrh_rPJ3ZhrE`tDn6buT#8zACDk~Xp>0Qi-YVzm#6@gp{`l(jRyt~ znObYY7{Dy1<~$AVN(!M|28w=%GI+}U_Tl`8fBE>^m5;Xhwx`*NNY?PF z$m1|>1qHJ_~iZG$4lgUA|MX~PSFfE$Q=+v15g|c zAP~WQ4Cr760c7D)yIam<*NUVj7WQG z38O8E6Jkag2#%hUP$4@Lj$UU7?9`e5Z0q=BH95o))7Z_dWJ8M6$#+6aC?JXOE&)IT zr{=!f;^PUSIR&q)F<2xA@nz+RMlxVz#8^z@2`mRxCkl*I7|u_)*{C-NN~xP-qASN_ z^D&hRDkGpfT^d#yh6uuNODD83VkDa)j;_i=*w2tA=oHvu=AeM)PAtq-GR?O=h(d5( z!Nbj|2aqS#21y~(M5HC4Bc%k?S7ifZbabGk(8@xMd_ZH)(K`{zIN-8Kw+@aiL56NE zr);EysS&v$X7UAO%CxL7W#E)r6-Wj~gOJfe482oHzG@mQQx3_A)CG~U%>bA{fuaU% zq(`?3++VTS07FnSgZK+lCLMH?R5QYlCjjw zPjqFZJ_t@e5A88ott*)=+%&!1`P1XmacDC<9Ti}tESIl7*==L}u$GHgAO8MV$7OLD zgBc-&scg14SJ$vEk>vgFf7|;R(x$c3u8cVG7)gk(Z(dGf=MR5+r%%}IxYn|}PIy?J z=Ec@R2|5@cIgkYwP7I4vz?ylVHl@Q++qmAoUgw5HWI1;0<;Oqjx~A#Vh91VqZFlj* zBo!ll^zw(}=KB5JpXSGR=MK~4KYw}k`9FB}gOB$9@OQUw;%Fh;>BXnpXTSL2_+pbD zf8XzdMsUko6}JOf*tFW?43zxoEz)Rbq)o6z_r{QegCK#I#3|>bt3u{7h3gDPk(TrO zKYabq{{8#^xbRBjly@(-)IgS*BXcNUJ=^q^vjy&9ePn*3GNkS>4K#!efPO=O;Rjp= zH$a17lRyJWoTVkpTd8GzzL3g2aqa0;_dFQMUj$QwTfyd5`%myXBB+r#?PNrmVLd^rv?zu3~B?67K4FCk6bK!B-N zmCa7dW?62zDUOI;C=b?q{^VsAY3uj03qRE{?H=n938R~gn_3$(V;WklQ!bR*YN}|4 zKxImS1d@141jBY1M=P7su#JLUX%F$#W~EYap%~nkG>nuYxDpIz2+W}d)rc#(1t*7+ zaK-RIAZN10d2u0#l}O+mAcP3&7*P=gac#W8?i^r630uI9@$5XtDjh;j2?n&jI;fyT z3$$?93RJU%8BnoV8-yF6XA)%fj#;e_$sant;<6-D?GPkLsv%%=g27?#t{6hTSV`PL z-Gf{r2)ROMtd(w3F;efXW6Htm4O}qf&ols_IZ|(UCL<><)YO<{wZ>RyHIZ|L1m$kqiiehJ2S}Qo@4jsEB8W!(t(Xfp4w8nXfGPx(=Xdbc^O2m|G zt~3x>W>HL}oRWuUQY1O4LNpB^F`xam;`5E^3Ko-!j!Y{q6?gz&tw=E&*gBUHdLNKh z1M15-B_kyaNG|Sb=)PhWB5&OX4=9GgMjH=yBp7k~qh0<#{F7_{TfYD2@1FNI+41}1 zzxb#9Z|Ckje>g$LYA`VP7VFFF{GVM;*WYAdie18 zetuXE-_3DSo}P~kdH?c@yYK&5e)YpR-afqklctRVpe{LG4oRQge0KBs=ZLmT+r!hN zhnw}BXuP=a!+W5V#rpc;tyN#4YM?s+w$p)jH&Kc&wNInY6$zb?u6A*%9ev8KfxR}; zRVmi{5A(w#4oS2Cbm6kUd3L`4yXVh7%T+gmyt~{!yF7ikKdw*f`F_3sy|4bX_FVk= z#j~IPS3mu18w49<0$SFYF70rSjRU8_4 zrAS1*yAe4o=>6=c)gD?q&wX}%cx*?zeK^lu&pd`(kLE&nZfLznis-61U0!#equ^Kb@+A==}#w2bKZAV=?6r86Z)d=M^+> z_Va1>SX*Bv7DX0uXaH<*RBp>$9GyXjlcfr+`+9kauMAZXH>xV~T*883_Rg%$^cQSIF52 z%TT0O7%rh0MI)F190a)|=SCm_8nnYuzzQ}7DFUExT`Gk@WP&r=;6o(SirN!E>yFv6 zgLa|;VbK5vu-&A$k2K_%Hd@zQCJt93n9o*HU`p<-w=5+(h5%RU$drY9I0MSarPe5X znIlcfs(DTr>sC zA+-?3Za}=9;Q9w}^^w_EPp|*qcd!3&@`8W-#=f7u^SF4IP{+|RBJJmP`gC`hfBEIQ zTuv8P{Jf;$V*Gkczxh{{#137(Rvk*h^Euu>@i(`p?`@!An=oH~`bm*1v-Y06f?Aem<`jxD~>blBA~wL92D~7){k8=PjS^57ThfW%f3Q z8&M96zyOkQnnvcfAL|*r^&yYu6M_ys62Df5DsTm7{WA|?C z)e+fGFunj-&=nVR$}~5?LQp-#xp^n*J+N62U zA{>bVTJth?h-@CxB8sL}P+GSvJ^;8arX zfduQChHUk4Az529NK8GLaitZrfUbZgmNjS-)ilI$fImYZx1f?@P;WjAyD$W2$-Mw|o!fU7pbDROu>U=p;RatY8HsWkUUM!=n#!(b2%q(CHsj=-+M z16Vg09i6eKa6_aZ#ZF>i6a?(+k#rNj0CgbeaB~n-6Q={BH$18FAVhXPv*gIw){bQ` z&$)9Q*}122f~C5+D0^K@aux~G5Xs)Eo3m|}1t=;YiS&6DTOfnfnK z5({8(ced_D1US(q6gm4M+_jVQ$g&6vSa3#E2WBtXby?OiMhi!bmdHcSKpm%K#>)~`N*KHg^_#bwxl*3w`IjGE{_^v3F}K(6p`+(58(Aj6EhTUhC;-}Bn=2wVB__N? zG};K}K;Q~JK|$0@r>0ZXmX<9ezdEVr`TpV1k&s4T~W*QR@1EmGV(OX9hN7J@I9)UI(3qrDW zK^lP#mli2_b;}7&pm-P{79sO;4BgDrUqq5 z)j@kpN=G~Q-~3vC_@858EE!Xppl=6>jU>bQvGtMS)Fyf2s)wsBG>6)WP=T_63&c3I z`&p7$JsS#5*cU@UZCX+e9KeDAL%mK|?2kfFzHK8*w*6 zgkeH$D3sltqLf&}sUfIh0TfA`f(WOG7MMiLqktJ9I6#A*fQ-C&KO2n@XQrLQ=(388q$AWvkiF;5m7FKQ zW9B$YZgWjdjY_wboRbG|qH+P?dRk>85Euy+F_#d&f_91k=OV;?Gax2xYe)v`T}F=+ zbkv00&~o00dn#e*icrjT&Xf&TQSK3O3f=dOk1ZU*BQO#4?4wX$NpMjhC==Hf5|wgx zQzT@pAqbK(aY@itefs)TpVE(iWPkUElO&0>pl7m6NC$P+bz7$EA;0+O;@PL4JjQSd z`qB3L>Gb=0zTL#LW2X73-90StRy!M>-=3-tM>~7oc9dyXf}X(;YssJg^1qD3yYIgK zZlPi1RL_-|E}z}(Z(d=_y`87exBO;~QecS&ohGiae_GzBVdOM0Fm5(iU;NPEY3vCj~<*^9t5X6O{lo8!&#d-TmyZZoarkwm#l|H=gbeQ1aC$FE9V%=bP!# z-#*!yV3Q=8Z7!&Tm4$}uU;vW7o~$?G60E5s0P$wS;fSH`4ikVtG@u4Sc7oII{>SrQ zpZCjFUtk)iGUPOj-VVr<#oq03I_+USHqYxSjq6O8JhzzP{hPNDoQg7qFlM;D-lof| z>&-hXyK(n&kJs1iv#>GV6Q}5e&LLNX4Tz0|uv^R655~x`kycHFnnKw_Un8-Lpk{THU(RJ}W{>%ku3>HZjp~CP1>@AH#U=Yj@JI6v(bM3E0|G*&EgdmgedO z%5Lvmp@aD$Xe z9jFHrL5kif5Q){rWeP{|DaX+xB}RkpjS&=`-C4vSvPT1eZW7*+ks^EP;DTN#dK2W; z5fWf%2O2L_&l2R$eRZCcdLW2uNMUypzhxc+f!$VP$%>H?AWRj2OLH+ zmN2$W>*tUJ#tuA`WmODGsV|MN7jJ}?EQ3^+s@m=~u_NCG`c7QmwDNJz{P zvjhXrz&o!F&_lLNh!D^gVl=oSzlHcS5vn~H(21r7M@ZSY7%$=r0C`HF-fA16#|WG! zYSk#Hhl~*&z$!OWEZADNNJH*2GSDVY{pMHj@cB*fF_tod0 z{S~$`Ay?GuJalU7UGRtzrHs?F=k6L2RCG|0ElKb@RX3-n{(!tG{03?&|ZuLPgc zbky_J)%C@WfAWui`s!oeX87=Tx93G^EW1xWyZPxy<7YQ`_ge2O?I&ao*rSM*%t4rh z6WQ??OT<%EceES>%H`gr#V|M`n&!Qbt{vEoqTU_;-QW4|ZIG$lc;Uh$=0cE5q#Zg0 z3&M8Xf$6i}tS(LKX`TDMAQ14{+H8m8$u2JH)4YJ5+IYKsyPGbz_x0I4uX7v6VRMxe z?ujfFWQ4HUVF{VAI(SF(kj&v!GI*uFKqS~#h`@QJ!62nj4q@T!sK^sojZLBkf9499 zBRt3&he84ZiD=LqR(E_ft=gkL)%N{|)3O{t=+o2jab38kMbDY$+IT(Ix~z%AYY6Lg z;d_VL!)BY=a^l$mL6nJ-P=Ey=&Wo_Ev(-?pTiR36BhxTVbAo{rTf&O5OVb>V$93Ef zV;;+wCS`AWQCqaqay9J%b-Jo+%iI1mS#K_E!I0z$JTPpF0abXz{&{`cQ z8Pk~SnqFS-x8{u8H6Q~BwWT3D^)i%BbxH%5Oi*bxFqdNL?0scU?h#=S=zx^iy$@WQ z7SaV%SS=*(-XszPsR=naGx_W)l)0~#$XYlNVC#^do4ps%R*JiVQzt2X5hAe13#qhOgBmd-}C z(^fH1Py<>}Ql_x*00D5yl*HUdR9wx%6f>y0H5kSaAWUly_ti@&kkk#<=46BhoX5i0 zt48Xiq=3Y05z&S)5myY&fYM4`nBL?Xc?8cTf3Yj|1$ly#Dg)!jhePZk9Hy4tKwLc!aNC4;i!MQwMsGUQyzWK5lP+cYII}+&wk|KLl8*X`(NMxMx$m(G5Hd9mRtGj`YYJlA!9vqOj*+QvXZFczj{I7oR-#um6@VF^OVYpy3WI{igOkoD?A?+`u z6kDo`+HlbuR5(v8M~nldRd06l4FNXK$arf@&W;b4carLan zut`osN+T+HXV4?6qk3fFT8%J}4LM?xpprv)F=QTf(AE_Q15CR6i~*lv81iEvp3{mYp{KFUA}t*O1TscMUy%z z3|n0uxasb4r@k~-@1FBkYcud@J#_5L**VGxVT!~g!7zGXBdE7dAk2G@)_U_6Np|j@ zDHYPq^(OBw5OlOQs~a>`w`M7^B^jt?91S`1Vuskl8No_GP$EYpXdVK%VjU5yM_HVb zgf|V^TJj_dhN)e-Jd!nr0o1{hNkLx-ut`8TQVwSGv&hiVK#xo*U_)&MB1#;@0HI2y zcS=c-sB18VLm&_}nt+$yOo9NB0nXS9Ljr~ngXT^H%h8OSNyA{=hn^#Zh&zWXa0b_s zVC^wboTw!jHgG;_bm0t9gR{G%nW)2m!cYwdXu6^^2dvpKICv<*!5+36xH{Baa)kC^ z+5q%5QVMT?!9reJFoT&@hmjlrbd?Py8v1f%ZNbkXP3&uw&P^e6F9~Bo%GetM2yCh$ zVK9*sDvo5y`^pgk5>cIU0EHTr%-(Q8t(MkkDNz8YXTdABMTi&GZOn~)V4~&J*I^il zJtM}NcUsB(=a|iLF$r6s)K)RhE zxOxb3vIP;@rnZe?J=-wQqR^DR;j~G+Np_UihGT}>UF+d^ETP-$HOYMc_Vub4p3qD? zVSqzKHP?Qe%X1rtKDYjx@7K*UU*L?=o7KCyO&6Q7_Ib`k(UxYkv;r<=o1TC96Y=AM zH}i+@-+c8QQfjM+_jax?e)NN9pMDbUh}(<%uYX(TWx0Rcr_J-r-5;Nho1oskYzHi5 zcXPe@=o+B;8c|#9Uxdf={XTy5j86UL;*}#_?)MMpyTP`g9h@1BWut(ACt*eeU;0Yr z`)|K#yk2eo;)lQZFKP41{dfNcV9?rDgjYZO;_#af@7^EH{Ma6NC|_=NU;f3*S1&S+ z^D-;+6D4{6<)>FazM0a4fBSW^)Ni((fTtlT;V3X%6qZiO=abDw-PZMLpe4#ylF()c zn=MFCNsL`nk0q@iemDP5zk;Wdc|__$#7d|SJY7PlN`iW}1I_oho3hD>lrn9$rLDd0 z@>-KHXW!lYw4LtmZ!b32&zIBVm~x(v$fM-m=YE*mLeUO44`$qZEnx5J}O!ho*cDz8K>&qZAG&1P?~vQZw--+9W;hq!caLf3(MrXq^pa5=v)c{)Oy&IErIYj zAfec-;Wb}q9IX!BPLwl6$!RS-kgN$LBBZI0M4iF{y#-9v6-XjR9EchaWbo!R_@8CQ z)&;|tC3tY_2_+JQX8=TQ3?Q7HJG(jnsu@s9rsqXUF&mLP$^mc)p9z`c#^aV9!i$0k zRF?uNQ@gjckI_icvZE2W2dxRA7v?&HY|sExB2^(qF;eGD0V{BjXi_%7a1L)y4PoS_ zJ`_{Nb`AmN5u5eA%i1xl`NaRt4}J~-t_IzWbrjTI5Y%(-COl@U-2np?9U&8hL)GG7 z1Wv^yYxgj61y49~1j)20d1TOTra@PCug72i;ltaf=x&!glyTZ!P3IQp z20YQLtE*>Ud`uS7?&9LJr?gQpJPQ$>d@QyzH^5+*HUFgYAci(^a`>z){-hB4u?&>3)?f&*nv!4E}@cMKj zuiQ-U9vphr-sZYIwfk@1z^o8y`|O6vF0NnLygERg&*xfMNy9Tn1T&F`jXX*w2pE6x z>7w5x=Bv+sHh=Z|x9{!>&p76b;qv=$e!teGdlyVs*ZF_@SFgVO*|QhVQhmGV<6WDl z{P{;WKmBC?(aw(Fw>L&SKn_WyoNXvbD^D9kv}n3`JKWia1LVwTbh#54wod?fBZEcFfN9)*-vZ^X29ajS=7x>>zsghgH zPWzPoczXLVZnmg3-+ZJ4%5yBF)ep!J$>}fnMx)4 z+YfW~(i^A!&AAc{r+s##4^Kzwa+JVl^qA_Wo} z2ONcDvme_`sCRG) zM^v-gs-iDiNsRKU=rw>SqO--u2oiz-<-#0@X~=mEqX>@)SqlTc{0L$-C-ZKaSV0Ia z)JX`#92p@9Q~?$vfIv1g2jQq4hdgfkai%QLjazdP)Rn`{8V*P-LEJb|TNQWP=i6yJ zr3=WiWno0p2(IeP!~^l!zxeogb=_Y-aZ0Phmp}dV%fI-`=bzl@)A>{b>+*cqef+~u zb`+QGyYkU9J+7+IPv@`i4<#zC^Sk%UhvTvP_SkTBo%YYCF^`v5;X|IL$JehF)-T_W5?Z6=d&iIozMu7TPWPu*rZ`Qk#zm#4$y zkvBUC*o+g5#EdN9biKhmZFJd8BWRD1!re*h;qiF3)sLLDwGZb$gS91RCImkzVOSH&Q-;;k zmWJ^XHJ%e|F zHqu&!@gkm{R!|s+u7GG4*U!3na-dxS#aJ7FfmbZgpdKy62)4skgfBMf>ebC=SN0>N zQ35T3OjS5B+QdeiG;m1+pjwwe&k#qq=4`$OMqZ9Ktew| z?j%L{$$N@41~7R?1p`DTpx_*2g1m6=loNmR{LTn~mv~I2<;_8YS5FiHe3P^}Rk`XZ?9Js=msA^&M!XnDfm;q`;IU58)3&dL0 zrHL6#Oe^+=j{JZ8!7mNjOChUaLx@N>AJCFycbykV16qw#Vr{Z^ApcK9kBZwh9j1WB#5EJ>zdBbeN*)tVp>J6quO`DzoiQI)VK_3$41PEl6pbYL1y)z*@ zmR)SGFVYaq4v68^JP10Z39*xtS$p=$CcS#)pyTy*S?AC9`G^1Yk1l&1Te=Xw+Llj$ z^u@*Hm``t~wr(e)9aSFnY5A_N`>PjoU*8^&XG;%r7nYK@V@YWk$Ls6q*)u!d>S-3* zCZ@F8?JmlAvERO!&bRH`-~IZ-(>X_2kHosanDVrL{Qm2cMoG{#2z9#H@2)O+xH{jy zJN0Icn9vpSunBAXn~QB3P!NINzW%BzMkW^a)l(QCVHw#yv>Tydw^|dV<*^^%zBY_! zuYTy~bGxgDrHdp367bJ&cK_(V{>vYJa=|`7{LRCCEjVqje);3;AKav}uHU_l2C$6; z18|OA;O0sQLy(!xQ>-VtJNt4}xfC!QF8L~r%rG()L{7{7_wWDd|M2189BE!Su@F(O zy%_+9otx+I!)d8{d^Fb8<@n+K!?*AM!?%aR^HxS2r{0hCQBU99-#$D-$=LDxufO%a zxwuHQ8Oz1965S<@%on@u&|~K=n{i_{WEsL_lLRmq2J6wr=rfwKHzzQXAVe@kLY}b< zK}2puLIgwskQfr723H^f+5#&RI;5CqUssLR=9s^|eR_X)xSd-h7{@{O)1J1wbg@a( z&?y(a|3GWYu{<1)c{|DB{^{=A=fm9tet$eJv$h5&r@HX6gpcj=`lHi29|OnD6@YmQ z11KEhc01&Jdt5$#cJcBD&!($Ov(q|jEa&sdp5~`qcBfNqu|`fQqKECKX*pLVFS6d{qN03#&w5+K;mVMaa zxd!Ycbi@J3qcH%2dkVyi>q^5AA_(S$5zJ5^6h#mbdSOo9Rq`C`MBGET)sq7$5a!Wi zD|%8$P=u^v%-~^)kqWl%0FncN;A}pyw;o`Yg$Vra00YH#hwJLqJz=yJn2DLYS`0q+ zY~FbkoV7<9iM+dccgyOPmx*_(vlXHh5Fu0Xyv6<$sd1o6_SOtNwmU~ha}K7IB%&0? zp%Hr621a+-@oE687X~b}K++iQXtZU0GVzaH`rpFO)Sr%bf{EKYBZ z@7`^vMz{CHL5|BG-n={J@i%WijDWX~R(AW%xVzl!xojq48Y5p_*2 z7s!whkcKp5bEP=AnhqO}mMq*eU2(zOl4t2rw#Tpk^v(bMe|YoTzQ5cJdTQ#)Z3VP? zJgv>rxnNC6J&H(xKCN(m{II-xSC2v8-1e)72Y$81#}5zdj5R_CQJ{?W^A2bwnI!xjsmZP)X{!D0Yy)w{`dftz3+pe>HwEMqw9>bS)) zwymWzl`Gg5ObJ6A0|cXk8&e0=)#V9!FwhXALa~}X*>bMS$z!Ipy9kNRSnS;4c-K`d zOF!W0_QN0F&(~M``OR_d@Z#n9jQ+U5zQnt;ub$7$nb_v8T_fQJv&3vDvPNC+SM*YZ zainpizR)l+J8c0_J*9z%wJxrF@Jt};nF;A!JGAa3 z;eyQT)0)Bq0H+*c?1NE4)0_jkf=crRD1mqE3|xz(%`Oi`%IHZ-3{9(IjHnNQC4q?^ z#{CwD5osmIR?@JV8iEMw8s_K@DH#ah(cnU`iS`D;jHKNIp-n_5PZz#+C`ptc8s)$g zzVsy7xWllsd2w=K3j|ChdUc@yhMvLCfaWw|aQF(AJdJECIVFv5)zb#8nr{pe>3f5h zNlpkQEF@HbEg4r06elIGf)}wK!aB${+9{GKARvRSq{b}JiwPD5CBShCN%3=E7k zkdc?hki`#hHZ0uFYjR(Qk>*a4kQN@F#eCxM=n)K73T&AVryiUWc54b5Kr?WJXHir$ zH*k0GFjyBK25Avts*IaL0kgT&86brv7FFW8fzg>4#?%>%*OXXI%7qT#n?Wuna!>d` zvw8}W#bL{FaM=Ki(AA-Z6h^euS>|DH=WVXnKTd6)33o$*SI_!2)3MKg{QH0T`oXE{ znI48AzQ6T%$Mk(Q*j?Blhd+IQH=`gcl9Dg$ zSoKe(eDvbwkI!HK&cR*mi|xhdKYspfyFb4D?P+l*xw)BM{^CcQONDpu^bTmsxgOhi z8PF0`NCPAy<{IcS!E&}XfXvAf3@lEG$ui4+M3M8~|Lx!YpZ}-R`-YgyyevcZMMIpK zDrPPE{rf&zH@DhOn=3w69|yjBb6Sj&%l$dN{^oV)HO(thhiz)ON=Zh3a9}|dZuo!@at0S$E zGvtPS#9enMv<<*L(c}P;1|l}^hyggDE+GY}I)*B@s`zwP5W3u{M(GDBX*r(XzkhdE z$2`XAe!07I4LIE2I*TJ&JKvVH)Od#;8Dfbk1r9@Wg>W9mQG7l=)&s;K*pNG$>rgzb z!Z?cSpspw9AnbJ+Qq7xs_$K+yK>cw!CZw7K41Ew1ujdEEV1*Ik#3BLOz>QkB27L(W z#F9By>uz{zu`9kT%;M0YTm&pob9L*g6K@mX_IenuhmvBzKyp2YNfS(od3z1T zs2!vv!$k8rGLb?+3Nk`*>S`Nk)zUVqX(1#;&xk!J&>iyZD%dTBcW=?ihzwPXO|t6= z1#vbaA#rl|7#Yv1=s?gN3BeL&p^8-2+OtqgZFMOUYc*qGa)VId+4Bx@&*q3QcwJL6 z9l}=w8NjHkGX)RS4yF{55f?SZC>l#{-AZYlvn`5f9->CMG}8;lC%W){F4lTicC0X@ z!9+HD__N#sxa9%sS$kCmH;AaB66dp^getpxPB>&a_uhI(X2&iJ(483QEV^NKZb4|s zgdnL0(>?feXXR9Yk_9ky^9j?*NT6X1z>p9+rb<@8(W$|(#ip8pVoUSv2!<=rGfM|B zjLkOgKG0^5%R{l$XB%10 zw!8?q2QEs%uCAFtBO&H1(8SsRq~F(~Z`!G^wc4Q$SI_v9K{p7G^M|{`?|${w-@ZSj zXD|EVxYpXe)Id!h`9dJ3k3YNm@}tAA-tC^fgW)vKM>fyb zUxJ^e{f;tu?}xhw%m^!LppX^jT)w#f?%%cNpI=^FzJ2|DFbXOym4*~yi}uz36GR|a z$AUH1w!Gs%UVQOvH+@DM98%$&=T;Lj6Cr2oPHPW9=47E$*{W!u&`dS5&&OEL5BH53;qqqchNn61 zkx|6M-@dKPvL075HlsDnG=BYk`u@Ya+BmRu7^=}%k4-?booRj=`fl@=zr6qUn|Ar^ z>Z83(BgX}*BX!Ot*c=PhGXRi~(};L-6>JwoCz5SMSUVDp1OUx!mMFopoADTrT}Hv zp0RlpVUy%$ltkJRM#>#Ek-@-E@3b{X@F8IhY1Y^%&MRDVE~x@rwKdX>A9+?DcTG_? zR7#?^{_Oe1`==Thaq4^n!!U3j+j*H?%0}w>WEKD#PANn0r%WXbJsGJ8W37S83Bx*s zpOm@v?wv77=d?zT8Z4Bjfr`d(-JU)egbb5W#o8q8fgS+%#=?|>P|9E{V(MP@)K2b( znh{ULd*~0EuCShrfQelY9GT2x0ISH}vZTc+00;(mNVRfA%OgF0 z5Grn!9Bm|DAV7>NGNw8kg{MqjyOcN_V8~L}N(HoWNi-xuN?m-z!Oe*qBms?clQHvz zy|Lt(Iyo8>vRMnpyt5SCW>Dfzjt%HJ*#nqE4(uIu6nop%VFjqSpdS6mD5|Ew>re=3 zAhU->1q*ubjUpuuOqslM2gAp95J@5t2wf6tR|U$>0uJE7U{R8vEXbL0Ib(>YqTK_% zOeken><%ie#WvZ}r+Z{tkA)P0(z}h1j8BxWXJ?r z0U!V$mefhDuHXTTX023wE(jg`isxfO^t!-q$aU)2u{X{M zphp)d#chek5Y=EHOd;eFY0PYHBM=IB_mU9?00bx@1UMrDz=TwzW~0T|-p}Xw@>U=Q)EMFf+nt8fjHP ze0;a|?l$JcX<1FJAx_a3qTuj^R)CiC85m%xT&{-w16{o6^@xp?W89Yu#@i34%-|+{ zULddBGYL|ywBb0|kfm0Y2Fl0`?pB7at?Oz5)|n~Rh8IJMO^@ycMZI_9bpa{Eei}1F zbXa51?@x%-taY3ciP!*5oZNUA1$!7e@d_>uiIxve60(nePXyo#B_u!jP^d3K=rt(9 zBm$aj_gEJ(ap~+UK*oFmPwqpA(fSlT01hTX)(RWoR@|H|0cmh*-XpU|GpEt4G3bD- zZ4y~DGNCo>jZkVN4tEOc1Rf?A$xa|E*aYDr$>S7s1A6pGkOx~-l?^44szxa_#);6J!=(l=8_vh> zDf(`c*TnS@0U-%ceQwA@t&IzqdLL=%+GUdi7&Gbu!x(whmQzYV5V$gIk=+B5uLgii zid3MCsHXr5TRAXdbU3>Y5RV!=hhx|ZB#r>q!y;OX0wrDc`!|aLrJP-HOobssQV3dF zDM)DwG)z8tM3NvyPUuF679Q&4JzO%Z;1MiA4!A*>5m!tDrD)Bg-4pv9@S5BKBlW;}NS@Z{z4!lEtnlAlYSMo1Y(4o?clh*D7NdZ02}Pv5`&>iOl5 zUcP$uhxgx0%19{{%QgX+5P6Vn2bh=O;HU4EF3(F|&);4A_U}IW@-J>a&cpD(oBs6M zci;To?9|ONp)Xb+Z@F9BCe{QZy)PI<(>86U_4RoUOmO((;>8dC(HAfFS9Sg4v06mz zK7G0U@y|BbyY}5{gdx~*8eKaOa0Ud|L>P>uSVe7iHExU^$V^prJH|E%(R`%Kt566%GE88q zSlG|O8NIVIow{!fX%p%+3sQ@efB@MD8PXU?QWtkMZKlr#}~Mgwe~ykc!L^l=zgm^+No zTV;vfoe3_XdvP+MqegfH4w{;w(IE(geNLG=MKMCOvtJlECvs zr&lIM$&sbnijPL>Y1m!!f)EgcgC0V&1U{ zk>w52Z5Z^(pu~t6%`gQdWld`^HS2)6XHKRoctg2b8=0&~k|`j%38GT&O+#^!89Q4J z=#DIPWmIxxN0z8ry+^o0KOa5vEUIM)%Fw};a7L)u*B(i_6jHT*R?3>ER$*B{psdK& zytif@LmkM$|Nj)>SF>hYb{N=Ax7OO`Gson~lbJWKzvT@8f-O2lw<4sD=+LWP6#8`v zy~u^w4^l^nWH*U!0w4eaRmCcluj})sKjw3L?`7tkDvgod5%q)#O$eBn6Ig?iQ3XQc zrGW{gHL5CsAyTUV18D+pZWQ7Ks+=oX17AX^lsW>Z6x6XXAPIngR}U*=@s=wAN^tEK z$mRuCXn;UjbHzhF^_ZKMsV&VkC6|F~(-&_4Ie%F;vM}%x~b~UbrCIY4aj_QSZ>JzG(!dq11cI} zfv}X}@bdo6)Lu`^@1NcMkH4RP@~by*pWj)3<$%q!s_!$p0?^Qn-PMD4-udLu9)9?7 z--K%+YzSt4Gi)w7hUb6#7x%Zvc=<<{gGZ-$0;9Vzru59K;1j&ZwADvMT^UTbx511(6PZMWP~TRr>LFOKtG8%Ww+ zfA{0>{K>z#I)7-@mU+pltwK(MAQB<Z&fa-64jVfDmuL51 zzuj)T2OmG^Ke(XzbG&(u>Y|JL(fovQv$do*9I;yu ziLc&!cl%(p<4x!iyH@tlo$W0jq}D#Y-A%vw<(uFA?2G#^e={Gm55j!_fvT+yD{L8- z0?2gthNwBMARm+na)dk?v3oKHi|9CjM@wS8I|4z^{gym{5V*5f52-aY)iy7O+xhJu zKL70JU;OOXZ-4n5Zl#+c%}^l?OW$eg%rOsLw_0Q0RZQsONZdhzh^2`!>Ox_yo3&Z4 zhDwMb_-Q%5xK{&=+O0co3K1kk(1ivgg4w2WSO~D%lBWiin>CS|HfQoUkGRI3MV*rF483w7bTLUWy@hAPxtG4h6iu-SSQ zMR*u6ffpW(ykNnaF^&=`3|*g`V<$s!49bMkdoWl?s*vvq*PsibIgPa-cnstX8yZWz zud#QpOKEOoFklLP*joV~&TKw`qN6%=)+(0b%j8yBC#=n=XLM^B2+aW1n$Lvjv^Mu< zq6ppqt*RQxOaV=qOr3g5gdurD#$roE^GF@zQNbL)px|9?KaYPIfkQs`xW?T)dju=dj)*-Y>9YD?z z-%?p&D3Aq0B^xLnYEFRSoSQK#H)O00L#O71e`Hn2m!|E$+FDxX7$K27zG!_2CZdK={KHFPQJ@Vv;t&kT zbX(4=?~b0n-o5pPn~UlBt5jmj*V}&g z@>g%)+5-K9cOP%Q`(Y0h$4AJE(|9jid5< z|Jh&v{QvR!;SNh-pkkDkS$BfgVs0&$$ys8EV98-JN^Y~E;1KHR)Vz`gOO|PfSXx@2 zfB0_Oz4`e4vy1D8%X~GRy?XoN@OIwkiAtT+!#b?Xas=e(7U6kDTi&7l>cZ-TLJ zmRyWGis0tJog-6p#1vdPl>1wwPGun+ z%3QqeH`}vQy^H-&>pY#1y||f`%8J#qBOsAMg%pB2X;#Fz+LrwRqq}$MJT0?YHKtg! zMvAM1d`y`$wmPsA4>Y~J zxx4x1{!ko>w$_d3U#a~`rC(RpT2%`;OJ=>gE%?5 zHtwT)3lbYqsW$CiZyvl8Qt$bw@zf7b&xeg6;G7#aB@kk*zp#xsF!s?guuqnSM4=eU zarN~`^6fAtUl=byg%=GapbF`wIHP7!w}o4i&Cn1U*jX1C@B82d8kgl;XPaUm&T z#Ym`{co-!G@+S|^-u?3*pMU>5tIgT)_(`k_+HA{`v$LamiDb>Z5KjtCV%K*g?h-Q# zc`cv-P6D%_c^pM6T60D4LLN~BbQW(w1DRqsQV$Rlz>1`!WW)(z0Bf88vAULJKkq*M z=C}XTPyhOFUOmexGf$OsBX6K70EEYpd3{FSdn>}?{D^9-`&M4Lp(YZEt7b0&h^kQL% z66@*SOfYoNJdvjq&Ng&;_29w7^?BkjXvkH8uKrJ)P8j7|_(0SOqino&YGs=QzhRr&w)@ehQ#^wx+<+QJU))pDq6I}k)D2O{HEmMD8qXi}u*4`t4D1XDy##bL z_QV*4umTHMbVq_7Ven7`1@r*OAla+~il_>j+_NfB6?cP@XYJ5h&7~|QH?IpFYKchb zz7&mwiI}A^hUmZqf5h7rIzz*NN?jB!=pl9PixY)RXy6)=)gT3mj7vo`^9I~4wQ@0U zYMV|KxPn(hh{*ZFkK+gbyC1Cc)NXcz)b4?MJMKSwdGpf=qfMdV9h@$ZN`SONwsk<4UeDv->$Im~%zngM(RNGJ*Top~v&eM1Q>|b90 z=-ThzoL=01`m0~;?oM+%rVk#x`{)1b`QEBxEwwxuJrW#KRUm7e0X)&@Mz$uI1?v?qM&Xu zwLkm#!*Bny&GqW?{jD&_VKGZ&RS{quPtShwv;XVQUp~tnhgA?WkdAZe%3;1gO@c{9KpQYR8b|67mRz&~ z^$8mT%Uqm;M)!vwJq?PR!5_Wz;Od9(Kl=E=qfai^kDqjXlGQp&->){h+vQRg18Y{I zjAp^yv-YvA)^X?=Xa(g2TGfFOp&9Z>Sg;mLmqAb786as~3C$Q2upuz=f-+DDxQU2B zaiC~GjO=P{&UyFMm!JMGzx~Hw?4K8I*d|Dtt0HJ_;K1W~4|@6Z^6?M<+tsR`_PdY% zxBq+`Irg2PcSL0=`=Yfj?xL+2QwXC&C9O!S;Ehv>s}A1y34m;-yN5`)y3m{JXsWJ5jY2?i|rP$%?BgI#)XWl7F6&M zu@;QZ9Gws)HZ^3(3W2<~qQ=TdjdRl|QG_0xtsh>Gt99286cVxZDu!9XJR!>YHYP_# z4h4`Ty0!rB&dFTB|0p0eH**#TWKwWIcDCS{Q4z&B0}vnvYb6jXA+cjyIW=e~P%W!_ za~8lRp;cO;)n;8><{Ho|Q7eFg>O##xz@3_}mzmOl#Mlry0jrj6Z! zBuZ`YM~o9DF=RCnolQwFH#JS!l-;;O168PQLK>Sac?s_OJ@kEuL2piiBw)^tOQS$| zyoar~v<`4%bma-r+?^~XgazT~KB6|V0Fj|qq-s8RD+UF5B_&pL^a@6Z=;}@z^rM+M z1PNu%gbc()=o)LFuAU|_?1zEOO;kJ)8W6IgcEX1V9I< zyAFk5wgxSA$q8GoQHb2E(Q?Q^2{;nfT9KI6LCA5c(n^ghfVxayy}kRXw$M`mM}Vdx ztf&x$^~CBxL)Ce?PhY>>-{T>tu^|HGS3WwdKZ>V3L&GdYo9>4efZ+-K-Wh$j&1H)_% zu94tjT7UH6_%Lk>-5q{E<=kIgpI?0I1MVPy{g3rDqKqk3O&vi1bwgAc%+@IdWYuaY z;N^y8zvts}N!z>Do@JH35- z--*Q0qsW^>t|0Si&QYIiyRceM&z|RUOLKqOzqgKO$ljMRy#JuT7>6aY)$`9^eD?AN zh@Y%i56=6pzaXS^&*zJ>5*t{_f|$`?B24Mu5cz%@a669HcIj!Fq8}3R^$>(=+<=&wu$p z|M$J*VRb&6N>kbIueR|p`MowYa%5i`gd_O?Xb!VbDB1{s)~i;lSG9dtB#8N7T`!>oWA)DR zy?9@7ArNe}GDV#-g@6+yG^>hW8qu9(W{&{wIRZsY znj2E#K^Np)C0U^uG&>a#a7Pc&)EfxeJ`fo&qTrIXLxbQE0u0a=L$3zlgIHx@axev*vk2CS6Z>3{u|fo`21R`hqv4Wk0kXVj6v6^wsp{6HU{ete4%Uu~ z3vh!!3Z!9^Ec@=%kenGsa6z{P!nuiw1&WrzoD~*yQpoC*VD?(G3tDc9*oixpEJms z=X+||tT|$Jqou*Ac?6_@dBzlh9TK2}7@BzT!~+cI#Yza#mxDb%aJYK^ zpPqm8?&0&F-M)Hxd#k7WT%wQCz4L>A86&>@$uC~rO+YdOuG4^MUEjqqt{+^-JnfMI zZJMU>^vIX8dwVx$l3EO^i}#;Ap1yo_czbJsn>Wm!u5dninM{oRIJafqyz}Vt>SFh1 zANoNLM?k1noRiJjt*(dh1n!W@LcNk41umsv zDBpj7b@uUkmD1~9e}1#zxCxsd{>k{x8SKB&yBRhk0t0VYNJ~XZKmif>Vof1gs{n|u z?nF}2vc>E2=Cfb@>;LfbdAdMPF;r_gmwJNx<#emy!!SFLdhih7xL&UwoUi-TH7Ma& z`XO9gtgvcA$T>zGhQ5?OQwjiY9 z=w&+$V+5k1qc=eenpjJg4~#uC4|r?+Vo?jK6WAXg4oOhw-%g;Y@)o9 zXp}HcL{SZ)9Wiy_g{*5eM|8Kqg3=6SXjU|ha40RP#Atw2K-AFs=77%DDPRC72x3|V zDh_MX3^0h@TayN^97D+ntRW%0TLWVk3)YGg5V`jnLr_r^slLn^eKf6T9I$}Z1{*SF zKTg(11lJb&HY-sj!K^{ZLsK(^qxWX=g zEp98Ai`4*W<%h{AATG!PbIs1)Z?H|VPRzuSO`sz-wc1)(cgWC#ky>W9qErr)B%`b} zo0*Du1s6l7{cK5f4k<9{lASxR$0QL|87Nh?fXZqWooX}B$NJmP{QJLnx%%D}bg@ia zhI9S+OdjOTS1)Y;)(|lD=H#-*c5+iN0kp=Y+PWX*;Z^tGd>OsnzkuI-cK7w&{r8?c zl>~P$_P*NisX(sXW$Mn>>FmAD(?{j=-{1b>^Vj=@m>R+Ma=g5Hx9g{`fA+I7qZdJx zP|eW#Zb)k^lZAm`Y4c$(EKPTGwuP5B*0>9xUDsyPR+i7dL34F%_u0TW#F)!m6;lAS z`IwKd-d=s@^i%3VU9I?#~QnBccTT+;7J}hKa z*4uX<{UAVhxcxNo^yIsb9z{9be6jobo(eqp-n-X-`j~?2Y46@KF%3m404MH(B2~c9 zulk-59E{v2XOVtO<#is$ynFri|NAfAdUjdaO!aYsK+wb(xXgv4{1`J8MjTDCWzUj6txr*?Mtv^X)1H(j=G*d1+Hy*m@A# z7kT#gKilH=)KsUI2xS1m4d2m(r)^?gw8U7@lp{ZR)V_G;D1a^zy@6vWR;fAmK_=F)#vnbE~Ba8A2yMxoksjC=J3IS~d?z6(Bl+S2saliqV0H8ubQb zO97(R8YAR_01oU*jHna?#()Tc&4Y6@2#$%8EQVRg^sf8H8#F}wc0#OPeWT>tyaAGLtfGUp7yRJH7HPVSHGO?$Q;2vW@zlD`}CGeTr zNka$Pj2SyZDNfCuPzAxU*Oj}K1EMsCW-Xh>+8QWX1(8-MOc@zDbUx)FrVzw|lQtJY zAdb<8PMbPWpE?wb#?n#Z;10~G2E<|QF=zmV04$K0v+wSfXD9n=@3(igo?!m+`5%7$ zcW>YREv;_OKiZDp{;2=>`*d+dGQc10?=g&k=Vqw^XKcG^XBF=@7JMUaTG#YZ3eIq5M2loU{xT*7`!9w zbh{ezeu6IP(zIC1dV2LmX?5t&gol-ku#_Q6ZBXjci~xOEN<$6nEjM?~Iu~|OpJ^Nh zjCIQMRBJmlvYeNTX_AZ1zoj>fa-@kn4gX_x+HtLTWaN2e2Fpg3@)hVkk?)zdzF=lD{=Cz*0 zntE&6s=9bR0#XYM=m0`CF%L-1xdDJTAT0pJ9GdB2e|!78Q{C$+TUy6Q53ho=<#utt zIXgeQ5~S8vkH)VJ0s0CT}8$U2Prt63%l5bg#X z0wlNLavc!!JYg;}NULZV&`_gBCJ1cHeZAeO0(aIRfO^dZV^Bh-KDvvHK`dz=;))Xu z>?~cN(xmgiyxi%yA$25_Qe6d3V4RGSY2SijV-R+Z?%b#Y3m98VPl1SeLGD070XVx- z0G~YeWG7r^afZBe_o`71oP=v}XJj!Bs7Gy$SlJX=i+5&6~e8xgMte}o-+)qtVvY&y1Du2#dpjf>H_wa~QE=1rY=w@F=d; zTmYF6O`br0A>m9lL)l3K^hK~Mnmwx-H3DRl3T8=%9CT#crv;l513E+_Dg?laB&OHVgMa`jB1UKm$Ahr^;8WP8drmdAg!6~E3soMRies%N) z(v#)QuuuJ~7u_HJZf^AY;-i23;eYed)zcq$Pu|bBTe{i%i%;wJvE`GnnxHq?pRx{{ z`)}^P{LSxT*FOKkKfAG;Dc4A#fkOmOtu5oaAN&5@Kl^dOc6xPl-0kiT*(_h3t3Vxi*-4Z#{m2x(UTj+z00F(^S(9Aljjp(Qp$=cih^zWblyl@y-nB&l6u{lt0 zC$1LGX*?hEzU^w8@8+fk~^62LN{Nj>4KX~kh zCSdA33RzSra#;!ZN zx+)9rZ*C{Rei&1vz8}tqpi}KHW%Xc8&uBWd*ZZ5t?|#y6*Rf`7%B3NP9EHl^wEg+$n%GA`vi5f)K zMGQ(&M^xyb9)z2B%Rc)Ido=KtEPZq!O+i;2k1Mu3II$UwiEUVnl>|%!L`NK z)M6Oal!T(w(Zg1BcF4p+ZSO=?D~f5o#CoUPsaHpF7StmFRicK@tgr{F8Jlp&BtljU z8U^;L#x7`?yH4s5TXwHYi-L(m0BbZru`t$Ju?q&xvwKLwjj+K)+I3`zwy?G~rpT*V z6+!df52toF+f*F|-`>I9Z~o@$yB~!2KAC><#qHa+(38zTEkvGZaXh#^?Qvv_uPdH&$)0nT^F-R^kz z_SF}+BnUxLq_fK>((}u&ez%RQ%z?yNxj*kaS=G~lL*OLRr`7cp#6ZL4YIU5TTs*$+ z`!J!2^TOULS127yx9w$u>Q&o`a^taI%2GTSfi{bEHbb*7O+5JcCB9fkd~s9Ska*_(1_O^Lo;pcVM#V#@o>KV`tT>Sasr&3xRE5@Pkpp`b=rAOmrwe)={8+% z26e%umVkjkd+-b`uwe5vNU1^rpaCF?3m>t+fQBHamd;4g5_2C}+yhtxWvUh1>soIQ zEynZn5H2?6-FxbP_`_#q+6!-naa@DXV>ZS4?d%+C&646f-~IM_6`)RnRu!B(tJ?J; z)fqD#qJ|YA8Ad8tctS)Z@ws$mR8-6U@4VL z4Nc&(&jI!K10qL9}Xek{vmV}O~8ObQKH)IPIj_5rxRR{D;&h7!NT0S8q zr+djs`?ZmAm#Q@`1p*jGb#NvW2aW1e!U#}MQj3IT5{v+QlmWc4TVWw?#w+s4niwPw z#b-83kj&QR)RJh$&_}GKJzqO>3~=3@)+Af=8PZ zCxzJKu3D7X>{K~oL(43ZY^9q!RVjFrt&7nh~fj1GkYshfI3B7Xj4HR*mvlT48jgWsI%g! z$T~R~n2HmUu}V`HU$iL2NJz3&4cLhlig}qy6>DZe=|bV5ynWNHI*Ji%i_uhB#^~$r zaDO;GJHDD`fOM*5FI;-pd71X`pa1gk@Q1%09{%~m_ujdDckDj=5pKsw%~v|z+~2e>KEL^^pYLAGa{+{_LCQuV25a zEv3j_#e2SZeD(PKZ$121fAZw13^rkFM1*R@)tb}NU^>a^j`1`Mbaj26Us}T1y>wk? z=lyb9AYunXNm}Y%_cEVoH5w*?U{HV@2%{El9i57IgVTmfgYy;k9rP#1@9-_2F>XTg2~t_n%+?_>&Zjs#7I( z_tU{DL(S$1+7y+2-PX9C?vD~sjo2(>Q|E+ir>Qo;j_PEMy(h6j`_(z9RWEEwBODe1 zWX~q7>=Df(^~ZeN7KNG!CpL}7%d!WpYPAvLRG~q!!}{WC(Wd)@1gW)G7$b?b;#O73 z!HnaObAvc(8_bwpDY?x7-LWm-axl<*PDP;%rexP|f#RvcO za6PsiPFEp6)7O9X)4%;i%ImAVI0QAdkj7Sy4RVT6n-N9g5+OZ!_oS(w0-|S1=!3THo{h&9l7ovg}&Jayapv zV>iTM=$9~0bvZ3Dgt%I@!vP2qnUG+vlvZ}QO=$&fjxm%{mixPJe*O2$%`F+sSjpPh zugkJ0B!xy*F$JCG)InQy^!8AyS88emwODA9Mr4TLO4Iz5?Aw3-@h16>py+kjSYUk)6`byAe}=*@*ZH%VZ#m%4pE%EEEWjWQ6!hvoqqFg0AoO$zhD2= zeQSQP9uij|$1)3V2y`92#z0fS*iGDqNcRhsbts$en_Zc$S(ifB_bJJu0ChDi*N-2^ zus!bY_pc8Gz!#hCdbs}KpRT|6!Q&4%D>Ba}%>@<;2*qJ>u-V#4Zx*<3DZ#}>YIrg2 z-uPjb4TQL+aZ+@|A~85L6Y`EKnk+}$o&}#(2n{Mp03c`{4MQ;-C=p6>?4g^T*ed&! z%c0H-l^o?ItrU8SJVJI!QcDzK7Yo&^U~;G><(qv2h{I?GD2h%3SR4?lDG#6SusQ@PMLE0_g2tD(nEGuFVR*wTvBO)}_YK|S~qT&QCEMg`|lhL3q zPDLAVXAYg4bTK=3J}vC6hLM$o7_=ZHhslLn9vYZ9I=ITnGS|fb6NwuWlmZrr*j>@H zP;VNzRQKYT00Xm$K?_RFD)pu%CR6FFsxm`u#DQ8f_e?!faT5kD-k2GR84*}1VGFsK zR4Yu-fFIhO#yt~uAx%LN1{Ze)0PcdDAY`4FC=r9U z;trJs8VLrWsd%7T$w9+Xiu7%6Y|O0Kf^(}RI5q5=cH-<7R$gaHYo-O5&;@8AcQY1o zXyAb=3gP0!0jXILyG2c?Ym7T1LbXcCVHP6A6?-d~Fs-ySCPQ|wH9!}L;#6IX=3LVd z2ZEAQ45|Qdf|$gcRI?CEQ4p-BnmVo>dZj*~%~Dx~Vl0z;^0r{2NKo0d=DD=PoBE5t z-|e8!fZf?6o9<3WNHK5-m)rGb?5{rg$UA{cJb!Q&c5g0UOlx_u%&o1Tz@zWPrw>_g zAyv@*SO56;|N7tWcj?L5c+LCU({yA?fr=YuZ2{Sk29W@M{qeUSY%ce2zENOUot<4@ zH1D{>`R$wIG@+G#waL=2w#{s9m{*&tP)&Uvw-E=fy4>B~ZLdEnb3X2m2$y%qS808v zv!esA1E-ErdMS>S#+8<1Yidk2*NcsuUcGJ*hVxZDCt%07#;MzDVQ69$AIXDJ+ zupQr7Z9crdejFc!33Kp(nv9Tv6&e^AXw&C&xzD=0<6+x{!~Ea_|M{`zIV>%0`x-Ce z?p~WT4Z7@N-!VC2gGi=}o6vCqacvXf89>H<>rwD5Q936lifGs)y4$`$u=x%7DFE5q z`(@o1m-Fe(Iz;{Wtj5qS+x^Wx?=v~@&_BL@w0e4d@%;}Tyw|PEtyc507;tl__10hp z5*DMdt^FJ;W>03#Env|gj3EsHp~`eR0fl%L$U>Qb$rv4EsLQdPCgU+zJKmRi`!;Tc z073#tiTm@|UT7|Hj8)N*NoZ-)xan@*&SD|Y)uM$c<`9C^a^lvNIwcB~j|tI&xUmL{ zAUd_0h{)r6@3LqZQj7#8qf^5HY>Ii?asfPeM35E50u8*@21yXXGpe~M;;Quvk(*Lg z5-?>X45lY&?ldb&wCwB-Mi$*?2ZT*uvx#-Nxc4er00}TrLd%YEL|*{Z9XLhvMcasE zZbS1$Lb5n|4ctoBUT7+TLc{Tc((}V?Yp41^~=OL4^aI zg;JH8p|Ckus6YWr15QXrK!IwZgyzDnw#cN`GFp&OwW^zsXz!e%I*OR~7VZf*4N6dPoE!pbQ|~1>%9-cAmj%3X-M0ot;69=s38HAxOnE)h zG{vyh0mJD4<7gzTC*gs(2D9qmt#U$Cz#g<)w_GHV%*PzMjsm)MQHoBvOIg5=hp%4h zyq~60PV39tQwSk8Ilc4IyD|J|y1S#}eR#Zn@btmh4VMr5%ZIvY_x#?w(`SeM+d~k; z2ci4%pTtLk`ptB|zxn;&{MG;E@BZOG)EhrP8@ls%ujhPUrUL-hxwtrlq&1QR3ViYK z$>qhP(DT{&VLoP_@9%au)u+Q3_hPWjMx1?GovC}RtJPKNHAwV%p17ZmFFRl5*N5UN z37xx!VZFY*x!XS+u7F2bJ+zxo`|2n~OEHyd|*W8qFLYrDAtkM&ez z2rXCWIt9_PG_mz~HjE?XQp`gaLwAPDUAC$KfgMPU7&O*wswc!AY^luKvq$;<`THMk z-~C^G>(M3O|Mtx!0s9AMwJVt;3@P?FHq zd*UUIz2AJjh?#Xw`rxOI)K#=%_{o^a_w{D`=S(vJ{|Bgt0lX zxJ&Xzj%pgg7ift+wCFAuN=1rp6#*(JJGE0`tccKv5Od=dpAI!m*g_&KFi>gImKL~hMMrf($0bHv z++(1nR9I5ChO!&lSh^&5@VT;A18v~hh)Saf)E#pCfHFx#EBA9 z2p)kDnN5%?0F;W746#5HS4Hq@0@9dL)5-)s7XnKus3I&CV(=&kRZp(f04q?}$s|Br zG@d#4os$L-%qOQ#x|6}yD6?`-5@2$#)Yd>pVs#tLPXxV%p0Fqs2qZNdDrp5iX*h>c zI0P#v$K>@bbb}MLas+bD3pxVMtqqtGPm6S(h}Ehcs;z{bN`b)vgb;|AWh5_+&B;UX zmZ=gV+FE4uD8G68v(I1NRM=%%D$4$dNF9}6W_MO%FJgx91 z)gct!p5NI!PyP1y({_FNoeyNSKRx@&&1Wxu{y+Zwmw$8m>g8~I4BW@leDlsKUS3{* z^XlsgO&SO81eim=d2sdg@skH1f0S0FK2N(lz@XFV?&~imP+>WpN^2aVt~Y&ue)ZK) zf6}G#*FuMXYrGNZ6d* zLlVrEwiFYP13M`@oD7)w?_VEIw_kqmTOV%afDCqRi93}U)r(v?W59;a(ZrMt~aNAoDpM+7CPsWA)P^O5`y*sP?g+(V%a-`p+ncl zWrq@!CB(I(k+8=gBED1_D#8HnAjubWAoUKQUu^*VbSm76>DzGHPW`Q2T*+Cw+$Dz# z6bUlsZZ!|FACIIXX_?xz=V>W#UbojTr&ss)4w|Ri`#PgiT92Csr3_sxWSz5Vl@NQ> zW3GS+^MAg1|KOQ3H>!k6+la zHt2k|M0f(pu5hf9*p`X}08XGVSMF$bU?~Po5P>_VHERFNZzYG8@da&<+C3KoFC8a8X%@+#ALM{*x5qfdn8x$X)zt?dZmuuWhJ&11v*Q=PJ4}aR`}p~9esh?X6X@8T=c0iy z4XdzTb;D-Ao9o4J;hU1};4`wMcyU^E{qUk3nzdtv+wIx8-rP#Z-i2=65vFpx3!973 zjq_c|$635=AAf(n4!`-?Pppgc-GN$brX^qsJTEO~2sFnIRYiM)wjAc%tF*<7?b3P+ zhe=7RP4)9#xVR+La(`oxhkiWFr5H)`YNv6)kFUD(N7v)o=G9;PdYZI<=i&KxAD_K* zCbjU}-^9>)m|zebwjRu>Ckh||&z$A1-a?z+ zz%bzWaofEX8EPEV9i}(dKhl2YXM#?&(s!l;#@$f#Ez#E z$DXq48VqFQ*Y-eiPbQN{v|J zGW7vDFL-_$3ZQXd!sV8&ZwVJIj0?=Q?RTE6Ue$ByPPVja z!2&>|*cWpsU=YZg#S)*q*IvESq8!;ovjEI;%qR2>hpM_*9TfId`!3Y3w_E8VLOIlV zqajl4RA$`Gtv|z&&wPl7=WkFQ*c^Ji-1z-#17n~h*iuK!v4%cG(PK5AhQR5ZS1FAh zcCI}b1z?eE%06VSiDrl!Qh;Kz&aNvZQ|?2{iU#6lE3zY|h}le%x8jXGBrPDpO(%uq z+?{eBd&DV_EMiHc2LuDd2+o_XFYP!>Q^4rjS16HdXfelGB%lUE!cvWC>jMn*(P2t80^HnL#kf`I@)nwl4{MKMr_ga%Ei zk0=HcTQehd(2}inK_-RBc&Z{~3)4WLiy=sWS_#a9o4V!N05oO44_aNyNj>`F z*bxbGRM9Au>x|Y3_m0#bA;os`u|ou&UE_d+1eRy&`?h+7>Fm|3=X0J)82WayF35Q= zsf$;ew0?Yb_2JX>Xh;n0KF6h-`{Qz+s%V+J%)AY9unhx|J4`w&z?>5y(*qxfA9Xq zH@oT%62h44+;sy&l-Ras7je@=7poerxE@P@lx?E!0^O&(x0~%loR0Nw9liO2fPV@IQR@H#>1WTcxohQkH=b z&uE?yATm}-7S{|%BS8gf6%ffH(Bz(^TX&dqls@$W2>p7!j))~xJCy2dd6xbV?oMw{ zzxmDT-4D;lftX}F&FwW!1k%!z>pE$E^)fwt+5^Jd9##+C5w~Z)Eg`DF6y6SaXF8eB zpcy;_H^pv+$G0%9F|A>K1(tw3h{F1e#Fb1MnIK^^VI)KiPQefW3Asnykx>}Ob(nh$ zGd~rhW$S8PI|1S zyzWMOcy-yeQ{%x!rwU$M%i0ayiCU;qPCJxQ^nmVxiA!~gdTKV^a4ia;5?d*`P43Ox zA^@r6@w~%ViKls*m(9@ge3U-4#f)6A-oDzYLKnRCk($x|)(N0M&U2r7FpOyp6>`?5 z;d~f1@{|AWpTU3rqF*ypK&(J#HXW&+8cS*!f>^0ECh6RpgR7Z~-&I-%tnNMdY&KF+ z?F<%bo*)@Ek8D1>OR(l13-%e!sJp<1)qrhr?>!~Q0XE(8>a8=o3u{KI+?w{IGm)xV zva(0+oIMCQ1;=7lkOLc7n;iRA+!G<52>VW(mIWN<+Jl=3tOJ$OTmm-7-LcS$%Z$i1 zD*0HKBNt;2Ic}&xM%2LFdfnkM4U)zfRH0AOH-s1hku$S88L%=oQWRt&l zUgV2^_=|t{^S_>6?p)wv#cLgriXY|!jUj|JDL9?3zWd(x0JdC0w_S1`)?I>iJ$?P=?)PV#Cx#IF z-TLfox|_})o*ePw(b_lM@P4QC%cOe?JOu72@SC5VmOvo-J)5N9I_Z-NM+&LI7~1T(POwqw6^u z{{K-{>M3PGmiajHT%m3O+5}a!Z6jbtN%MmFG@pu4CHU;~;bMC@-Oa9NtIe0ceE!+1 zn*qAXfEpkNB)&Lb4Q?Fp0*>>rUdsV*Pe%nHVQ5|_H7MF@+VomZZ+BReaU=A8NMweg zmu{O4#47n&04xr%S?ez}K0{#^_H{q)PARUcdOyTi`m)~%MVJ~za&*rkU249gZX0ml zQ3_o!Qs_42{$!LR1_N1lzWl|1Ip17_fh7%qCt6<4yh+t-olr8u8F21d7=X+wc{K7S zC=HMi79=vQN{MPiUAnNwl8qI`RZ?Y>TCF7Bc*l%E$e23!6QVjt0z%9l2dG(X zAX*S2Tanlt02U^yMg$gJf1y)}#k3lKK|vZ(TLVQCA?`fy~;BGFaHK9Nae`CvwVtAZP$;+6iU_;ILHc#J~i@so9{dMeaH}HAAGh zXzd^(F416tyf8u#1`_Bz7jKKlrtDCyrB!bfu+bdp!rOv18e_vm1Ri>5)rBzeJfk~k zfT}i9gX7za_4Rf5-R&IysHf|*;qk{8mrovF%C23UU)iKd9X9;UO;bE*cdvbjo4UF0 zy7}zAetUU4|NbX`|8M^A_g~VntX8Yk4-Z;9)iR&vyUn-_fY`7i(S?Tc3whnt;>$hf+`{^Y~;!-rq|r+>FUPT4epV2Fmq!hOJ!PmpKyw%I;X z@p3$DFW=ElN51;v<*T}T_W1EfAi)xJyq;dXKHWYaR~Nu65~lmR=?IqBhnug?o_@6X z!MB0>7k~M;r^Dh}_ypKREDI(P3}w!-E9xK(5VR4oL>4BnoU=9eVei8wThznekV%(a zTar03&BlPGU=*@WyIBjUgPxJukQDb0j}P;xOj3VnDUEXLFs5sW`rR)1+S4- z0DuIpb_6&g$5!CYKm6OT{`*f$rpFJ@#Toh$R#6ZnkZ@F}7B)-^tvb_%_}owh7ocbr zA>`sh^T7R`)0uUvp!XE6sof${%c4VPN4+@5)O(#;91_$Px7=E-n=MwY>tUHcG(Uup z%6fIk_e|mPY>#gb`gYIbT6C|P4SL(Xur{`(*n*7)3zg=^;;u0!HI4?%r?;4T)gX0o zDo|I>#nXjbBSrMt%a+*PE4YEFgFtWqG6_f_PliqHkQI@ZgHR;R?k6kQ4EL}1(4*P) zako@|f46@|6z2F|?(BH-2j`pnyW7;o^UD!POb=KX6}su9$}+cvT`r}W_hTo;X`ZcB zN}Z5S>fDd!rH`X`=w27EBU3^nc;1hk1n;dZfI*=3+hN>}L((V*hy%9fZicUC zQ&J_N1qu}Dv4KW)1#C*(GaLcfBQeY_SUm=49$HX>SPdT_wNqZCvS2|~RIuqDoScLf zCcP2t+_IRv#9WU72^^pRl42<4j5a7Lq8kW-Q*CAfBqW+A^Uyp7@`)`qG)4eGh(iSi zuAyKoa$jNgTx3}H=B*v%xUJ$N^l=TM}ic9u>cQ5$k3w{qyTP& zilE>TKoJ_c1Fc>64cGjC{OA)00|cF2tU!nr#0ZVpNQpbErK#7j0x7L^n5#Fd0Tnnm zH-vIr)Tmes5kv%np9SWCUC$&QLUm$E4+(A&4W$7OD3QS-jBEhZK~TT}U?Pj;M9hEz zi*u)50F=E})2I?CA1#BI$vo72Txu%0xYlf-6^x0yj;Il$brb|?NIDk`!76r1i#a+u zc=o8xfQ?-pp`klszi4_O`xkn99ZEyvWT8OoCE8mt#8~7J%vc``?Y1 zE7TssX32{+zqo$)-EV(%{o{|@;pW93evdQ?VK1G5Mg*4BTFG@D*4L}Et5=`?Z2is$ zR;LIEV5q~gKfK*fw(N%Ow(HJ>k7VO=Y7im?UJmyGR?E%nw0?B<^ih94;zu7IfBnCF z`k#KiSS2P*-5~7bm;}0f@#ur)?yUog0Y*e*@?whG)U2VPJ5WKeg?d7a*;S0y8#y;L zHAak#cD9v2`?C+`xj>Nt|7_bG27I4Du4EKAKzBzDE3cZI0(371o zM9R(40GKG?04ysEhU8w{!N!q-BdTH3&}}cyL!4R+B~VD>m{ktD?fEzieK!n!iWe7T zHxoD{H(N5!+KRTNWyc(#Ptc=SV4BGpY$11G^u`EP!DG}9ZcPdzm#ik7Tz~echN$Om*kJN<(7^!I~ z%i~8qNXKZ=+SrGrH6l({0*VqXrOxwGIj}^5wm4Q4aEv2$>yjyp`C~Wq3 zxz3spuh#I+2Op-0<0ds}r=#OiPN(e0^7`%W?7WNI&HK|_rOq|<3;<0C#f3vaGlgZ& zee5|kNh?gS9NSXOTItftAg{Xa;_-uRs&Re3T?NLd=2!}_sKG!Im{Zp%^ayARvMZsB z5U|NoGKYvky%C~$bZrI&F(J05&1k~}QJXUYG)4~5xPT)$4bBE2)s?I<4#Z~AFeF3s zqE(W)OYjPesICFws4ajNYYAd&9DvcanhSMk>fp_pNr#5o00YhoZqbh32;1ZiZj7xu zI@KNZ1680}i6}%5iB~J`5`{H~;4vlcB}QZELWdlU1RYR(k&YZHdh(#i5v&0=_tB|} z2X`fQA!GnhW?qx3Ay~v?&3I}Y#LS%#09@xKU~Lv15d;YYNhJ{)cns=-QVSq1P8|U< zMsZ?q+G>!#13wv}NI(;45wSS|V1Zas&C9|SM>MAxK;?e2 z)l0wn@H^jzug1+oNicfcgu!jz)z#g-bCqp~{_xCyn7Q8N+dY1B_v!Cm-yT3#akaUg z-Lz%grmODq_V{dfcL)`0KD8QJGBiXYY&f-IGrfI%`_1RSfAF(K!{}TI)5W2(b+ah9qR67mp%lXA&a~bC)pPxT; z=`ODx+#RMCGmqP_>XyUtbpO?O{vf0j&L8Dho$g9^{$c8t_^_kZJ8ysWZ+`PX|7>oC zgyXpFyI7XVz;#}<;l4hHZrq?KTAd~jC?R?iYz0G5b0&pEfIa3J0tJKF+&Mv|Q`rl3 zOc+A@!FNBn{%CvtIG+CT^V`(W+SKBtr2l`C6ES* z+tFh0;!urfF;#EkkWtXp^_c6hiCEmAcvc9Y#|766M*z}58ZLF32euMBW)zn^3mJkm zgDxam^(rH=FQMNEpC}a!A)vDupdlCq2WM17t7L-(B}L>3Ik^Xnvu9IUz-O?PG++R5 zV$UaXEk1D}v+QA`Y*rU?v@V9)YE3Y(@0uxC@Mh+Yury@ETEUeTgXB$nWUCdSs12P9 zgR0fa!cGj}WW_Q(J@*sr}_Tk-KVkh&HD2CYQNjR43{g- z`S9w-3D@UOOv(5zT}XHJi0|Jv0_fxN%}+o5H-C4W-MbJ$S}P|neLN#KYp>n8CwFwU z0%{(~=cPjEyTQqo8)bwv5DT<2RSlM15|!mR*Fb@#M^6Oho&O(2_|Zhm>I?|%mCPUc4Q9bk*{ zEPRpl+$Q5($Xd`Ca(Mi!fBF~y&tJ52-jm+U{9BS|N)Dh=jYk2_Kr7OO=7_5^Qe`Mq z6Y{xoG2%Z!vL5Kece5qZ9; zQ%P`<{R@f#E+M{Oo&S?$GFqp%L28;w0 zOzM*$HIVF5ajeiPw9RV~=z$gBN|G6tn2Y5TKV5n~Z^pQ7WDTaSEc68SfvKyXS7)X}?bx*T&VE{c$3R#NrK)by}GZSzg!~`BR z$Lc|Zq$D9DjmV%YmC3;nH}jb!L339O5DpDRB7_OKt%-e+LaakG#)PO$CrQCL5M1mKGvKYS#Hc#ZA(l3lvt$6IDhDG-L`y2ua`-Wk8Hz0SfPfguwUUj<6t1 zm=<&=X3L%b4?p;WfWW{;Kn9&l3hzMZohS_*p&6l#b$DiI4glnRaOT1~EWosj8H{a6 za+>OnxF(vCCoV}4a>7KwJ4W+q;+%j5Ap`|$_a>Mfek&n^fMfEAm{2Z=bM#Gm!#WKI zxxP1WGg38Ib2B&S#;u1!Yzw zbqK^T8h8z3&c>59^b4M37YarX%6=+mA_2ZL@LRPqz^ZEa~#i*U0P5i;poU z+||0n@o*k-j#7DtF#)fa`!D}ys35v+qgl8h`msG@2{0@pTAuW8|LyPp;FH_CSJ%tWzd1i5 zh2Or|9sl_6Pp=lczrskgOQ{UVM-*~WJQS%!fgqbjdHUJE`OE+6pI^R&!<26d)tu>6 zr<9TpuGzgXlN3VBA_UXSxsmNjlu8j_ta3>F-DQ(^9#Cjici?AUifWbI%vX~~SmG`$?D-`C`1FHpl8y>2g5@!wuMP?^Q zOcnhqNl=}{S%blddJsbIfPpNbYgiF)oOUTdm~CH6sE~tXH^|ssO`BiVtp`a)L+l%@ zND+9*42+brxv_w=O>^}{AD=d(BEa)BzW1Y#rd)SZqk6kOUgG|#v#f95eR#O4_0x15 zrssFpT&Gw%muhi_bW_WL3A(Xl0)Z(f^WGNd+lFcC38$!z%Zt>u2a&>}Wc2_`ipg{UEPifGA#68Gj1j9Qymb@A}kzRgd>8u zk~QTcm`037C)Hk(185kaInYK>!xZzxele+m9>jtb8##1RF+joYhyhOCoT{4|7BpZy z4@@jYsKo%WZcdTBMD49>5Wzmi3bM!Shq^nQWU5haa>|gVz3f$3NrF>iR$^l+h)m%` z1c4d`MuCZ7fIA`}qXUs?U?niLBnJPpo&+omgCkbnp^R8A1|gAD+#6b|wsrtVuHl2! zyBc=tBpyvA^+vYET?Q9$Vn&n#h=Xm1iXi5@J&k~2QIW(o&o~n0h+beCJUCF$o=$=M8|)x5v`3l<&@-Y=Q%NHlDtK`igyam^ITzgm zl5s$g01`wN=uSa}WcUXtuYR-nKX|vi_{^_wz1~c7-kDRoT)*~**WZ5gRG!BCa6Vt3 zuDYA8uXT@lTR4nCiNcJM$A*Sx zT^%q*5UDZ!;BNlzr_(2|p4;o6Y;T7|(9Y}kzIXgVvJYP+VyjA?%u|3yI`M9w=E@XN zN7s3K{geOjfBPrzKi5N@4@nb5<|HNvoo9+pgxx6vQXp8G1Qv(FRe%e)yG=>2Lou<% zZo0^1GHnf{?Hb!>QXVJo-~Ax3G;m8PEZwfc5~7ND*KIfu~N)I)oiPV>h5H3tA?->X>)Z z7jkzrYLRyd`;*22VGXZIhA99u!bO}cQl@j`*nH06fEi}upwPvs==mnS&46vYg3`PnB2b>91L=ph_b~Pep za3fjIRs%7&03MsAgy=$U1)?L2jTsF|*X}~Tw9%uF-feZS(|KjiZN+{pmJ7SP4yq;D z3cmMPA`y_A5pAodK@o7=(;&bNsVGvo0hJ(UjDb6XjLZFy4k*xpQF}tXHUu;sDHEfw z3QYqhMj>B^GiPgNkdZ*WB@$;Nhg`M|cESe6BnCZ*ed#Gd56FdZ_y+mmk)QqSbAIt* zyZM;z4r6(;*N^?;Z@ziFk_FGn8X{f#dRYie&Ad!gJxsSBe=pjj>fxgI*XyzxLl2PL zfnVKC!N>h{yc{xIrs*)xrFK#Garg3jx4YfLPrr%77Xfpfrq)LI=i}ibX?pz4yT|1* zuCy)JSQ}&IHneb^ZZ2=14ySo|1sZJWdi7ubhd=rLAN>94S`bv9FGV4(I0;Q)r*rzd-|q5+ym5cJiMqkFR;Ic z^MtoS>k$PY1M-cefrXGPc+;52yDxw8U;V#-`B&Qy4ynKZfy^mabOtOG;pi*w?x2tl zMPs(}h*Z)Zb!F@$5>v8Z%;9{bHsa=maB*!SIl={I1;+%20A*)1bGigfM9JnItq4V; zko6m;AoSRO0(}H4!j8D3V`PlJK`GRUOg)MxLR$jGyFxe25|=9diWNL@N=862uEYf{ z-4Ftj&wIA!(~N+~6UGXo84=78;{w|=s^NLZ;eg^y?5pC8a3;*e$y1L@!)$)Y^0)x9 zi!mhD=2`&O1Qn!-axm?PD25Vk>sk&6SzDi zbgqD=22m)7t&}L1PNyT9ceG*KOgo4?+@ns`7L=__$8EOkH+pJGd6TKE6zwp9V`1{o;oT;Nfn5JiO|8(fC7Wj zgM_5_P8l#Lb0BG9bn<~Jax^pF)OMLPTEP$`W?$b~y3-TeA)>+i?4+lkam=8yL` z`%ga_%8yS^-+b{kbHV)~t*tM(VlPuYZ;u~+|5J+(JS3G`Qa;^$B*nK;PoErOd6;iM z{o=3w$NQCd&NMb_{nOw7TZN+Rp6{hx?te+Ss!3~40C=-Icps|)01zzwI@J4zLj%0OU+Z%bN^sV=J6^D*b8mBtUuCpahb4%hEDMuDbvY z%`!zZrJ5mfp0*!8tDk=VbbH6!FaPrLO%F~XIh~%R7q{*GFH=3>aLVlU2Jk9V22@Tv zNW&ua`|D5thkx|%|M^y)tA{{0a*2_0BWh{qiON`LAlB#oNMxToiusEga0jy_mG^s@9gD_)gAf7GmXnUf1 zW7Y*Q?AF3%DDWP`LpTD$86XpHq2jzis_1TX<;AIMOhU%gIuh!PXgkybdd50Y4@-qr zFh}-HGo&FKJgrc6{IuZh9{Yg(XlaL|XbTa)aC+o{vpPlTBciVN@-|W`bE5_ppb%ha(*OGE{ z=#~1r#W)*rAaeuEystT-XGxv`b!#BAKDNl#FZsAPl2jpuD`YnFFr$o27M-LfT0#eA zN1Hqh+oQ5 zdE_aE8j09>>$aWn;H!sJldHV2WG z1pxdypkH7(hT+otqYI#>lmQ4`9brIU`!-F- zfBW-jo1Q%r;lq5Z_LuXgzuzBT>%wEh!khq!8d{q^Hm{@EY@@Ba7G zT~2uhReiYHdO3gn_VW1Ha{qX$@BZ>vva6r{oquricm7WM=Fi{!>b{j7TOS^?q!cbW z^=-l2Gx(Yc12K^+7)X^e0tmQk+3oV$hAIGhAbPg3f@cXNfjI5(2Y>j{r+dW9hsUqR zvXLb&hr{j%KO}ia7YIpCOoc&=T_8nH3{%^1wCmxE|KI=RPyb&Zit|f?Jv%~V%4|-E zlnMrjYDfitqDaPbaFfkI5~8EC3q!j^Jy1^gwB^DOj>MiO^b2`0GSnf3F=dp+>;$Ud zj?13%MM!K4Pc!uZ?3i~H-4o&j4hi^5p<~0q!D$9+P>h!f+&!5q()vhh5dwtF64Yoq zAZ}oewyFaNL2+-2EDZ04+$FG3L&AWLc!+t=yNX633b7)PD-$AXGX}RnNtx6;0SP(*6SyusANq18$c)zX@mNlUBPBt!1TYpx9vb8+p%Qg3MS>J)oh%0IyeYhq?PUK28V^EkzV#*i>$T~*Ou1;Xbrdu27+KjOCrm=Mpz>C@xaE!+rR=2Xs%@vyc!nf>bi6Vs0nQ-pnq8Ab9rC2{lRzbAmJCjkAVM2?+D*up?^3 z-Vxb0NOcSbU1@-VyBtBEC|8Rnl#BxBAf>EM%#`{JSRzxdhZ{&HP4G8L@-+C3>WIFxy_3mVZe(srW#BY@9$&!^`nbn4@8e3{@? z?@z8N_lFOO>*;QO_3`i3dU*KeaeMss;j(oMS6DfwX;&iOzj@%PJiqxd?H}`8=9^bz zxeldR+QUP{%4>5_z#%afciqO|MK5l-rxY>^epZlOFljS+kfx*fAWLqGJ&X|3ZXf4M#T2mo z?(>^ZULEVJ+w-4)^`Y%CTiVO<)88vUxQpNX1>C*l+@RbIB*7<;yD%F}9z%V8^NWA{ zPyX+(4dhwMl*6Q!;WT@SE6FZVU}8k1lzh3sZo+cFNRTYpJcyZ7bRda-4V+^?ada3f z%rA+DQ^oBO$`Q0?A~#90&Ll7$UC0rydBRyPm4J~}4Af=!|M1a7M!8-UBIQbmRn+f3NKDL0us{_vvs~{nB&y@WL6{h{}{nOb15fH!{ zLhHl^{py&3UB>$%dohh*_aGpkAigr1^B(=tWrssS+#<1q^e_NONGmc?_q>a~dU3=< z^o6uJkxVk&T>~=`<~|gKRd(`tR>M@&*jh#iVZ@6W157|u;E3%SzC&0;8`K^5_okqX5dv-rL}FPR8IlKX zV3T!Al@RHeyADBO@)1Pj-k6dOy$02^EF_6A8iyZB+Kg?ZZ{O&&C(m!+FAwMY`S|L< zUhbaHx9RcA$8}#0LWdtcub;fw-R;!x1zaD-<;lUP%i~uHIAi6I4hyxk<6_N^0E0k$ zzw>`J#OCd#C5mU)cJj4};1q-KURV z9RA=tX*$~gmKL;&G5`-aPB1wj8=Cpy@|!>ZC;!KPIc zdXTdt7F$*+29&^D`hb)p3cGxc zZm_*&?*Rsp$TGl{QW`xH4w@LQ*1?mA`w(=cFobf5zNpHawym!O+chIyt6L{x=xcU! z-;6l{TZN(*;I_n!c_&POZ&t(bK_0Q*cmCw+3Qj#r%;&z4B_3s$huL^s=Lt1@L!Htr zBH9DY|1YU?N`(5IKPX=g@G**>f}Bf%TkeFy}@@J;CZQLAWDOAUkas zDTQkBeNT&8KeNmu1R1Pf5)zCI2=H|OB;{7++O=RH8(BiIP-)}Jlmo)I0Vx^*I*^cs z83=jDX-ZX3$28AS3#Ecgfhh|Le znJf7SU_=iVUb%0bSV^#~STQ`i2;gvQ z9Wc;4#ofr`>7EY4(=n1pREI9@0`6t*8rfv1zB*Vd) zQpQvQTrrDsC~`eUpN%@;vxmkHO?UN}^FDui^U?QSj!Fx4mgzZhi00drxs7v*ZGF6~ z?_U3UxjsReu`iq^*Ur0I>s(qHzPUHTIq%8O0*L);X}`w-c7AvK{@?1?ua*xN*K+&v z6J7P$_wSy6`boS0d3(RyKfPZrj|voNW6UXG?|mxK1CsAQeE8CtKuS8Kc2|NKAyhu?l#j@qXH z$)`RpyD66f6sR=8W=yLWp+zkdDiego5OfUml(0QQ5r=0`8MI*@v8iK43tR)!2n0_% zMDVN<>R6%ON4g7`FsfPl;CBc1|etftelmJ z)*%?IaLU*^F1DVxJnt2?6YkAqzvn3nUe6yc$K!Dj0?XJo&RA(rO`KLq6JrSqSUc`- zz;)=Ly1#ZOC%TozM*@xz2%UF#TQh;^eZgS{XhH#s1`5E5Fm`0^SmgAqR3vtkq#@TjzX{dm(0XPTGP2VTMK`d*J#O`1zkzu3~9_-!d1og?`Dh4AO zN?>qmtBEi&Sb$oLL@2~-z!BhzUIms|$*lMYrXHL<29TiSK01cRw43|;gJ!pDG_2Bs?kPww&8$2AZH+pfwd~8(J{7AzT!-jD_Vgak{Ccoeu=nvQg$|A zj!U2bxAnYJ!Q2 z6Nn??0P_~ieFV!`S!`hx!wCRQZo+eq=l1NFr=0`)oc9%LJxD!N$954(226~7yR=09 z?Ju^co8BIG&p$rge!9H>YkHP$cQ+boTtA%GZQahxzk9#C{mp0p+5Z;jj|zfOkEK2Q z)nEVoPyS?Czv!z9UMhU%hbs%~#)C!8t_=r@)$dygeaF>@UA_{Opf@|M~4+KfHc?$4|}YJ>*=DpMB=g>^{=5`Yt)os><9c zO*D0rx;^!u{&)Z7zxzp@Rp(;PJ8YL+S#m;R6HYpE$`AsBkV#xT5MuMqg4K%%R{{#S zAz4X}FccR=Mnq*~O$pl)a-ebnei`~EvI0QJ0UZUp#vbuXX$Oo%;iLDY(gRFF8pa$! zF^qQ=r2q}2%|>9ZV%^#WNH7vm;4t<)z#wZ_0tiu6TYbvBI=F@$f=jdqX2LW0Ol~rEr4e z6s^}I>XOG6Dh7xkB|-0i%#wtng?6bsdU_(BrC6;J2|!`q7gHK;INDVK&}Ay?`Q4OW zUB`o7nwmK$?dHB1AgzxhA7DJ0Y*9~;?w{|<+xyMNb-ic=1;Tas30rKVH|XqpL@rs9 z5y8433=I^-rK5JrDHl$j%K?dtpPQC}NP@*$1VK(X0Re(v)r0~;G%|%hV4hWa3ltwmo_gp$&7=TIsw-;pkD!EdoNxM3^EP z(4H$nnw*Ntg*ZC~AxCUv2ux1ENHG?`k02Hh0xuY=GeiRPEYXcCY6o-xN9&q73^5UQ z3+GKLt2sw|9E2TR2vDYkv{Toh9xK3(!z{N;(-cyz1?=wqPferu?jOu^+&uyqO8#`(H+_4IDu*019uo?kvo`%|i|NaAOoO;2Z7QG=K5 z-TQy}ub%z*)iRg$>gS(+{`J58`Q!QV_x|qRdht^B&tK~K;acqR?K=!jN6EQ-{fO4E zWa(&AqPAQjVVY(I!Z6IarnwJCH3)N*@PG)%0KiXf(r4d2$P^EMeR&!=6~_tW<#)<= zKZeI&^A2O56$_TdxH3;vM@Te<*Z=yz`EUQ>w=m|UMuqomyF8`iXq%=vPac$}NSW*$ zA%;%aITn%>0R#f3IGRrteFf)$9xjMy^yeTQz;OUg7yu4Qc=4Wm2|OG?H_U{6Cf}m3 zu`5wIObAqB@??}!jBMed#3=_-!p*uv$uU~Q3b6p37&a_!o1nWg3H2D+vOxezCA&fx zh)0w#*S?T3OcS6RX7Uzg2f>KwyodDy;c-l8rx=NodmoeqYycV)IGZtAXM#Zp5%(bz zRX_W zMl3XCcyxzUg@GwYyDkm%Sg;paLAM@#LvrgdrDSVQ=Ve#v9yyCCSRY}F>2@BB#az(x zd@S3;bsceJo{6`$r#)p&jsfmC(YoAZnRfG(4TKmKtRjvyw1XgYkcno=HiW^PB1Jer zrw9#ZM8}aFvf3G>l7?FeUyxDr4fxd+oDq5#XBGD$Ax3zKD3pUY5U`Oo?C5q?XJVt~ zk#{u5=r!8KLYTO=0fO#;sUgr90a+|sZFv<=}_$$WQ{)8-`tgs=y(0|jDk0keZD*Pt1R3D$tsZ3e&h%rx976QGVR+0+4S zXXC+uxuXR{Hx8qcifH2yO(29V0xboG2k;V9P?0fI0c97l$#kcjz`{Lk^|SQiv-HtT zJ{?Hf7;A!7;^EpH^*q1N@^qd~1NJYzxz~JKzxl;a{^lS5`m1xB^XdKLIVCwAU*3H3 zvM=x7y?xu&iMdcQ$po9&!F@1fo~Bt<<~h~<+LsF8vD^IJ{`9}F?dknb{v7bId-iho z>X@t7ydT?TdHr~~K3x4urH~b-K9^}MSFg@gVBqz`!<4A6VL&zIrsHw>=K1cs-+uA! zczg|c{@#y&oU^9dZclqSl<_hh+Rfu~|L^|4|K!7m54OQ*Q)Si_%qTcH>26K)MJ@lOwetMx<&=-6 z?-Sn8uCV7Cfcmg*15`9}7QMsTHDr0i9NH8-JGV|H1iVaRH`c^)(3!;OVV{i zU_OvIftm6^IFWZB9?7^(1e+6U9}s~#ODvGZ)M2F1Ko~@%(HziW3R-h$=Zw9C6GXFC ze9nRteNbEhIdf}k0SfS~E*Y3^oja2$zDf1|w=R zT!RW=SOgLWHUI@wf(1My1DJbe3^NEoV`S+L|1)puv+7%SCIZudMC@cON}+KXnQj6K3pB*T#L9>$JOdOl@dfo3(^8 zIKN1T{O}jQaX#LC?+34b|NHIzYflBo^6uAv^X~1t^Hu%&gjos%%PF)$C3IwTU`973 zK<8AmdH`bIF7IA{{^Is`c>kTt!pi zJ<5&|98dFHq(L0yW-bfFp+P>JuYUbzc{&r+#3Q!RQxgLhfOc*H>{z+Db&TKQ6oST} z`#Wq`!g+ocKm7FY;yWLe8-M)CMaxabl=BnTXZc0dr#E>jI16&6l$;jgk_&dE$EW-M z;s5%NUw@0x$4=N_kW7SFxJyovoooZyNt~TBMiO(Pfk3gFWvsp)@nk;KlSi7ft(Fs_ zqdCYFqfsgj3P~c|BjeU11rl1t7=ct^D1hT6LCL#=Uqfbxj!KSqJRXz;L%}B)!8AZ7 zvCh6PDdouz$aGC8ABL0laxmEk(ka^{qW1~LK8TVx0@fMhZOd~&$+ zV1yt<@<2EX?%h@%3>nb6p)&ztAXvf?OAqg0)!d+U0A&m7=47FaiDM)~Wnz>$qM>aG zyw4LVDOMb=GKD(t(HfTRe4bCZtZ;pddB)LV3=c~4p4M|{!QIX;#>G-e7-+%SV%sdK zr!wiX_3fT^CBs!4Z{6{vB>nbzmWLh2_RxQ8Lj-};x6VTm$9^i2GoVYvd25nn?H0IJ z1gBagr^0iVB%#~F^@iHH8L_F>ROCdq&@2w2iIc1Q#Kb`siFn-%cDbm!DKIKB4#kXo zg>J?(cp%N}fwH6Vm}YB%sSglHt{BI%E}tPU>40 zT&*7@x^fZ%^`3HprtSn?2RNa3a}j*F7?t83sm&>N^E1XvDoQ00DYGDW;7qgtC^$QI zbVHJ0Kmf-H?F=y>W~7a%1?@u>0RU^n&|Ww@03%I62q2C#K>^q>6~tlz5)uG_tC+V0 zK+{e)2P12Us@kL5$SKE*kM!Hu5gbU2z8QjJc!4swNq6HaDL`{D&!!LC@~j;_rJc>p zj6)`lVg!;7$%n}RpAm@0MrCjQff0Sn#0|r`6I5i-kfZg-fL-`i6CfZcLtkR? z^$kn|bJ3xtCyzGLzDD=VNMHj&-@gClJ2iC5d*(8gqpml*BiROP!`%e{iHG>0j@S41_YR5D=ueep zh#@hI_$_uaTye0VHw~0hnAxkJPT#2B--a!w=ffa{T^v5z(@coxfAsV zo1VeqXpOW)4h}b}xGjJQ5;<%rCxlK7VG_rRJ`e~nVY!4)OdBwRRY;DFIDG=e?mOjzN;EpOB~gn=k1Q}m$Ki(uO< z7J#GYv&1oM0{~wGrIQd^4l0J7U_$C(1rxfd6Mz)&26=#GTRP#Nt5~ z%xHm=^C*BJ-r%=FBnkA^LK+#mh6NIYOzZt38~pUpJg%jJ}O> zIwo;<9`=s9E+fnFbTxgHyKiCTn_BDgGOz1ssU+dNy!$!}%!g;!^S8V?P@8DRq)q!4 z6|W!MaR2I)eVssb{_KbMuYdmSSHGF3=jEBCdMKxI{q^UEkAArS{vEDgZ{J>Rg2!L~ zd%Hj6w7-rkU7j2hR>W;s@91O7bt8w!V_g%A_RUH1Ebg81j)hw1hsO`g_47}E{~vs3 z_ji8%*Z=0-yZ0QruW8Fq8NpMC^SbtMCEe=0d-iM+PkwpKr&%#Vp?6%L-YqhJ`iZ># z=3S8j;o~yO37bYLBqeDZgxmx;i*5ZHYC%MZ7#Z>Re)!_k?|fV7aY|afz#Telc+ZHYu4F`ZF@XZYn4(L}G1T&M>QIrD4 zfItWZ*-$f>Yatlq_JM&d5i|`1FSm&=m@Bbk^sqUUb<-a=P?9cmQKhSbDO3ok?ulr$hwg!sCIsdIXkJ0uK(Z8Nkpy7$I0} zjUsMy($=*ja7c#9p*td|J%l5A0W=061vCh3R6ern+i;4px)%&pUnO(XsUm0$%eQ2Y zwrznUk%MG1$H7V{^QIv&03}2umW8>xwt%6Q9U-MTJ9TV>PZXUu-3Bz;S9Sy-vg1A` zo|33wr36C2!Wafb5P+}-mKY1NB212}(-BEUKb5FDuXflphbhg$i^590&kz<{;Ts>AKLk9 z!?!9$vj_$TTYzs#Ap#T;IfzJu!RWU@Bz0hb z>$W_tPfz9Dum1gLU;p5D|Niam%K@lsD`EELf!1&zQ>_I#e5`gY6EU`SzL+CoM<_9d z!tOgi`0R9=!-gP-s(as-9)t#T9UWWmeN9v(5zKj@dsm>u6t`7B{{G$b{q54mW$gv0 z2?uFE{?U(bet3)h10PP9D;f;HYLpP`l;8jAum16W{uhsDtcZ6U^DHIN@J&h*N)jC< zWmT7n)tDz7V^DT8+<>g1qN_S%1R=F3NfSfAcw)$du()9ibrR!b>jlSfP(<*AkeOIr zdZ3Xuj0EAxR~JP*z@88%m25O1){q=ZE&z!DJz7KEK@3R4>nRdO>6QVLhj>KrMtHr@ zZdb|#NWcNpM1&|65h7Qt6Cl%Wa$#;xJs5-Xh)Ae`jeox#I3m;DOTW)X<}vy(a5o6r zDTMQ+G6kVyq9Agvpveb#;)PRSAcuNH3_33O=AsYLui0^5 zgKu7@8{^u!uuw)x2n~sl2_T1?IR%4931El>?w|;e$Tbkqx7flXMz=uI%a_8n!B!Xg6X^f!+fla3F7Jq5Xp9!Ygz` z83985>bwG6t*>MQn1~o+F-!Ja>uXe- zkH^z~e!5%+d7cu_^L#kYFJ2rzdRcDou=?`l&wE>`OkoQpP9NRmX`lAV9)5QJH(xw_ zbA9+~eYjWchjxA1J%7GW6CxC(^E!Mq@C=f0?F7g{Q~(SN*&Arv@~#T7w9Ql0odm>D zZeRcG&mOkF{`iyceRMdsrD5CBA*EfKIFoJ~jp=wn8j8#wxGQCvLZ(9sliNT1{{Ev% z_vg!&050Wrn(uD%;m+61hI4>R1$IEw>oS&e1_uh*)?LOw`qA!tuja$E_x;U%nDU`M zF228c_3XQ!5k93RFrOIR)11bJNvQ7EcklnjfBBDo`Zb^#0h;5otz>>U%#I~2!h#KB zo;WrEH9!PH+@juK5ig)%*c*TtnPaBjp;Lr%NMHZ}nL#-E>bivH5lAiE9lV1B&;*F6 z8!`}IDIB)We&^C6AK-YzoTw!iXa%2oOm~ zJ5T_4fFLM=VE0~2B*uOro;VGv$OPd7Z8#hHW`K+xsSIpEY-=ZNtvecZ4tHp^)CnZ# z&ZVg`bV?HIVy2PBgvp2OtM`szzO4wOMM6?o>Dp9v@gPDSoiIQSy?*-q#mzJ>(#5P@(wP9T}eoG5qa#!#k1bc67Du63rI1?Gbe!eW4GQuy8bOc?}g5!mk_h9w0? z+Fd`;H(?Ez61SC>xMnW%l6aX|plHnEb*!^i6=#doB6NQI%7fvaHPh~ou zBrhe;nG1mvUx+%$j`fMhKzIX?#Toz+5V`>vS%j_*5Gf&s!$drQ0uyo|Y3Gq}tiUrS zpi~70W{6S%cfkp;0+8VjFq04TfxT0>4`rTb!3@OUbKgc18U_l{ESs3Bqb(t>NM@#q zJSBPdi5sQ1!v2=0L)S8-<$RN${r-1< zZz{FL7K4W8%C(~G4|$#s_1UYK`Tp}?e)IY3wI^}c5vLbFOvg@#XAfU}@%k^mJfGd? zqaOEg^PH#H8gaf19lNr30oTn!VO!k|4LwFVB*_yO$P#IuC2=g9_hto4Kwr;gg3%t% zBYpjgUwrxHzc%o7Ykl-I?-D4Qv4WGV+Y;Iqqp3n@w6V0SMQ`i3kKN zh_WzeLr8lth)B4uzOLQ}wueC&uAmy`HWV7N3#5REkW(PyO5B^p6L$`I5u3sW9#^AV zghz&8-=IE$WWWs=eH$ncJv$&R481E33`Ts^1gL%3W0V=&!XvN*Q37a&0qo!yn8P-> zoP#6`!xWk!dJl>1V%g9$VF}+sIl6)^=7T&J7ocr}5nvih;KLzEDoR&dtmg1x!Ng8X z$Oc);kXX!-k-8JO*XV&sJk2~Lq!5UX4ou_{f-&z6opR~h=7zR*>&EI~He880u@FN< zazs}s7OWW@VRSRK-f?K?l|UL@0=Li^#6tm?)3%glJMflCjEOL~%texiY6K^=#5tiy z8yG2b#r-v9j*5;M(1MvrFbHGC@k$^CA zOW7DmkXZ)|h{OTPHUcxL!7%F0W(~>#*8s3h9WX|CGf*@@#>ub{JVWj74T(KZQJq)C zrSZ89&S6ds6>Ez4hdKusU?)N_ZqwnU~Z_6|;;QO0>Ii9A& zv%A~VXD?2lyrNUT|MKTweeu#GIZ-Kib^NVLt6n{^pIKfA)tz z{`TkpuFeO*xV(SAZNrheaIHJeCC?M+2(?T?TtZiOpp2L&JufKYklp*`cuW;l=5@?# zQ(#=KDJPzQ^62I`Oy|@7`QetAhqXgWxvde(AHI$0l|A>KGn_s>-tKnSrylF-Jv_3| z4s6pgPzNar5CLtA3KAo8E#Ldm&5P4#$>{MX4_9Veb8MqLKkWbLd!XN%DW)AKrqO{2 z_Is1N55NA`|M0)~)n!PnQ=V}@Pb7?zlMicwMAEtR1lPh`hFi% zMiGz*;s_wtm~Y7g)-BYcKZSWjw`jCoFoyJZ6o|B$UhujLY`8vo%7~1-qbbk?Tlc38 zJ}8Eg6UG_Y0X*aywOgHHo-hP*^37pufICs9)f{&*8eWpED|N-d*anWSK1_CwU}@(5 zWL|^92e!0b;;lSM3Q9>8w_PfVioTW@?>>^({P$5{e8X za$!gilE?uhAz`E$ddiJTnz&@|Kmf60I-Y_(htZ)PEf1%zEqO~Xo;y)MtZyGHA_jmq zUAI0KLL9bcPE*;{0yx#IlnN-A5dyIjc!*R6 zr0|5vyAU{I8UaXYhlB|wpmvi89V<9PkiqtCNz~yGNE#WUIfHw((bd&dAy5+lMnFmD zi^s92S)&q;&P5eX(G+`YGR}hzs69r5HcEC1V1<2O>&<>wdlpVRr<@Uul0dG6iO_^< z00*u}Bfudxf`SNv!Z3pNM2%svtsE61uqQMR=mCL6L<&d{4oZQ-;E5240+CYeiM0Z)Tt-26Qn!q{`BmfT zgARRqJH9$!5$i|4|Hp@u+Hc>=u4!H0{O0`j>moea_G~=vh*PdGm&06- zH~IAO>G09ZvO8?+>o5Q8-+ukm&)bLQ+kjyXHp}$xi=W(o@g?uD-h70Z{liuJ)2r|Q zaDSXY@%~r;;YrGy@9TqHCFBK43;6MnGpMsT^s1e4FnoN1zj^@z<|g_i>b%=eyG^-}&xmzw^;ypL`=B z?_=$Kd1$VVc_cuC`-cyz=4KYgg+DpeSD(o7Mg1@~btION+(>Uf`eZ7!-9NbRjKv~i zD!xDZ{$@Kr{^>vbi*I!ol)w@>71rcjBz5p%&WZrc;f4$bDQ#Q?C9J!vo1Ov4=6wd? zv49QIbNp6HfCV6BGN25-0nG$V7GUA2h>4EPdW-EsO@bF%6;T1Uu-^h&@2$#!fK&t6 zZG%*tj}Xj&l%C5PBnv1-Tzz!V0TmTTRK;w8BfL8RE{3qGB^w$T2!(tJoM1b9&ZyS_ zww8jrk(;;^L<<)rZ77qcDcERzh#q{&wq1f61ArTF!Ela2y8_k-x)zlb$Q`kxc}zzV zCq$GTI768N$;p+6(EwN2uA~8jqJwo;Oc6whi00+G4wo_Pu#?W%0yEc0s6KSHq-Z0m zLQdow9!jKW2Ef_c!1m#y2AgNW)N>M^XXpzxvz?T?XZ2RXV{jUd{>^((k^rcYYKD|~ zu9TA}NhXx{6Q=2e(=H#ToQeW?v6X@wm!h2}fiw|<3t%b86VU21MNS?tJQ3~Cd*y)W z=wOT?hN{wCk#O6>1Hv<)SK#DG$s=6MRsc^@_OuX2MmkFr%}xkLJIH*zQI5oq4s zfJ2P|cm(evo91TFVyCgydQZS29=Pqz1R9UWWmWO#F z*{(9KQF8W1h{~xjV5L0mft)NvN7N}2X*0h6;Fm4o1v3rQu4EcC9C4H0&5d!in6@@u z-;ImLv-!t2Kl*#S=ltr2pT7LtKRkVceEIg>Pk!>|=f7+^UcUOo^YrF{9^1ICiw$QP zFFyOu;p6Y^KRT_~hu{45FTQ&HZn40U_O~?=d)Qas{N(H3e0#aSJl?;nCzrHUoWU4_zrxOW!KnjPh+0m>oW8t|lF&QBeLP{FpBfq?n!;AYj zPfWhsKf8VLYN{Ds-aKyW+lMlPQ7Ht;^tK2-uC)q6A|7pROP??AzV2WBtekw#{OUW$ z&wlT-k3PPYR5r$RI;NW=*KC2Vv<2pT#5`rBLTMKG{wLE%&!&C(%D;L8fdX<8%C*+t z{T+fQ(Lfd~GXTS!$|)TA>p%OK|Kgv%^K*}@B3xvyd^n(AV!PxrF}4AtnL}HA>0lc= zL&=Bq>^eY3SuhKpr#^6NFb2y6BSJf4Qv_6u zK^6eZLpYJH=m0i23E2g~R0Ymgt1nFl;~E2Xu1;NzLQ}Z7kxd0JTda#CU}iu-3YhlZ zF*=12Z0^Z@bZDky;8;Q}Jk&;jJ0yn&o*j_#j2TBD=NS_4 z#bMEOjkcCKTXVrSYz>2J*S1~R5Te)?m?Z!m+=)`E+ne{49p~!1QpMYYsmf%1zB$YY z1E7$!Zf7$!Z2`oiL!M^2KCA-44123`@sc5tjVPcj=h+ zKmL!|I_L#`@>sAVu`xDB1GK2Kr~x8CDRd1kMvMYL2M<$ShXV9&!48Wug>gVQ@EBs= zsh!zU7xPtD<>-rT+ByYn4P$g`jV!$BN-1;7Ixe2)0U*sfh7>p9aPJhWOiw;_O3fpJ z=KZb~trONGCRU#IDU6^{Hu4q#XpTWhhCvjF(8GsQxEUHotf&iMjmY8XLO}<)=CaAOrTop?w}^Ur_T6&#eEw+v@cyeeKmXa&r3n+09CkM{v>Yd2)U~!xUs zyf0_fMh45%Hr`$Qytd2b_SMT*Klsjf|D(Ulxof*FPx|4_qR6Ev7Rn{Pe`vpY|M+-+ zl__D!^%1n+_Yd~XpFQ?3|83eIZ+`g6CqJye|A*iI!xyJ{o?VBHHq0Rgm1G>&&!aC> zs+I7jz{}q|9?M~Q)35Ib+Co8FS*A}u$uCah`pCRXB@+YHiZu_sdHV9F|NZ~@Up+MJ zy{j%BS=)+>Wo9BK>XlEPcF@%G43alU&^4L@56TluFkz5JbeBQh$)C^_2q7aOhP#uZ z_b7q9M;{pyL3dV^3BoP0^9ih*O)e$eJnvA=I}o8-4qE{nGg8cSaa0UY)GdJ76}L0{ zh7|yrSOExA1l=eV7+3H>GMsi873>Vq+!@tFGYyR?k%4wXRD>1FotHye9&o!1KCpM( zI&>Dea*9wPzv}e~9uysI3=G5HA|?n*?1CO1Iba##Y6&Q!hnfXNkS?4um4pBuB}gp- z6&Y4fW=_6sG&YckNZJjD`sTea1h8z|xkUuiL1I%HftUmmRrZ;JKS%u{hypp;5SO4t)yH|zrzKw`ClJ0t|bJmNU^ zG)=^VBxVCj{^Y+X0pY(&6dVnJr&5+RO|!-!Hy4tsJFOkn~ z)hUB*of4XJ+rT>1YB;g3h#72VbB$cw1u-K)-}KFUtPZ}HC!H=YcNd=z$Im4v?4-!h znv;sx?g>)3`mCcV`*!K=CEUEc{M~=^;lKXL)gK*mIo0!5?|=S_U;O)j_wzsb$K^d( zOvnA<%lB_Y6FzkGIc)}OUVt&t+%Y7psEf*_<&3-JA+8itf}jDB-@`D{4m z^6oL-{>_t2`@H<-h^LSL;D^8aFF*hBhc`K~SGTH--NA=coM=Ce!kBsf{KN73I839j zU!Am)cpS18*&ToQBN;0B1iQp3W63gf9Hw<`fBWzLpRXTAbcu)rzqMXoT~0YNI5qXH z^|t6bD_f%>5R*kGfv%!}wn7st2HU`p#a1eV0+=DeY58oV#AR^tMGeqS;NJ3js2Oti`a5Ei3D;hvw zpzMQkV0Q*|0GWVTNn<-}9;9v^yFpkDaN@0HBF~hGodQA$fjk1y*9~m7O=NE2VL${C zmf^Rwl2^!ud!}`hj#3evs1!+=7bTKt8aN^`CqWn>t)!WREMGWt*A666hK@8Bt;}9Vi0Mw8-fIdKpSvboyY-0%yeP_GJpt(f~-y>M-R$koMB+!+^5Ys z&9OG*=!OWP>Z`(Gg)>G-Y>tG%k(iy4!M&pw(j~hWKn!SY7cCU5yNYcA0BtkrYZW(| z#18|M-7)Pz%87D8QkTIOv?(sxHa(R9nd=@M`Old512AE1@$&zwTi>o_NkxT62Rqk`ry^> z!+mhdW)X%(LNq{j7ZN``^F%@F)zybo=!$w&qu#ee&%0|5ZBp+n@f;>!1H>uC84f zn~;3?y&usQIUO?l%d3wr#!F!y4lnmFK4#iw%6UBQcLNRc)%SmRIPABxu8Q88yYp^< zVKiiMCp)JAJ4b(SC z1vRL*XdTpn1Y^WS!w|+Jwk7r{Iv_Lv2c8HL+9tim+EELjhd9ugnSYH?z99Jw@HTSr1pmZFeNk5L&4i zlo%gFHF~dbtXS?b7VW3XPP<91#U;`Q=v(P5{j6*;_K@8|?0J~TOE4zykxuY^O z^o~$X(OAPdz#Sk`F$LA;bwrzu3P3w9+`9r!Kzj|dk~&T)W0suvNUSt80Fo?1XA~r8f=021KY;_b z4jqA3fHT65R6_>Ojd(yV0TPJ8>_UM8IUEPT{|%5J1ql-$Lk@_Y2?)WFC?eb_*5Cv< zxtov+3fw6ACsDAWM6! zPl^{na}ReG+Ugb-W3s!NSZK586tWSGLnasyA6KEQz+nys$;6$>l9WrjdX6`r;ESs= zWjdUEeZAh*@BZ@7e);9&GOKdJIVpnWIX~-}B`S0ZyrG0&u_E&-F;r1(+%t^lYyZ>^!6x2FhjI|N` zCLX@|^3xyx@y+v_Q(v{$d1-*6^9eNCxDc1k-mmpE?04(!qnY|SMPIsFM3nu`=f#0! zq_nvAy)IAv{xs#CzJ34V$giG1Bkz5!*7~_IH=oA+uK2TOmjeFSX#aBmLAev|=RqEM z{POkskAHHT$D1jyH-E6wNBN_Ni{JbBVqTu+`H>k1&|a6Ndmix&_Tfm!Pe0jB`1Ex+ z3~~f%TkKx#e)ue3k1^j0jgiRlw>FPqee>q8{`)_9tQ?LY?o z)?7rGsc#*N&MJj}qlS+qwv`iXhM=bFCdVC+lss`tByg10jSG7p zAiOHnvz7@Eq~TN3V$^2z^DX0)c3e*nRQ(~|?RNP%6iQ?rTXed(z>UBr$A|1GQ4u1+ z0^(r{s1SRQprW7Lhp zf(TtGHE_>5w?0trt<%*cWtWEuQm%Ot!pUW03StRe0ZKq1%+5C?w{9cA8l;g6J7VO3 za8k!7VgWNugX4yj9h8}ZNZf!VyfY;OLP&saQCQuvyH9`?PJoXTH||PU7z;B8mCPu- z<3S6iL_;`%Pst13ohaIG{Zb^vxi#7o-8g5F6sK8@%R7L_^hmmc+N{_0Eq>KDu3 z|MJ~0m#@E`pH4L@K^_XHad-Lb1(ETZI zuHK|k!HA*mKYjrt;<#f<^vAUZLJ%%>-LiKw;ynb3UzQ6F9WK?e^)}@$kXt=rh~og-{Ao z??ewReeq}i!=L|MRHZQ$1Vn<82S5@Ya^Y~a;BaV7-7JxVXHFIfo)LgELnw7AxPpzv zSpc&4FlGxvfWRFui&{l=7zi>`HSR(Egi#HXx9Yreo-B9V9enPpYi!lAxTDRhZ`npi zt)WcIBYA{TFf%67Ed;$NphY<13Uh@_C>>32);iS6tn0qq=r5wZ^I*{Ui@coSp$7hHAia@&yz>p9}s;fgD zyhm&^bydAh%)`t5I6;BN0%$8K0Z3Mdm@+UZ3DqEgfm$$7P^d_WvL~`=O3n!d$RLqQ zXIIpa)_NqLCJCEzV45g9$S!>GG&b4+Dx^KRqJuk9iV7KYC7D_hw+`BoAb?^}#ZlVg zi~)>c4gwOJN!peO0AivHM16~DIWTj`q$qp^S%xBMk~B^!0Sujy0Ss{j>_8qQ04(r8 z9SCOBOjZ#LC=6#O3+zY}cqZ8quE0Csig|L70D_c&AV?xs0tjpn9g{h?h>mdruiz&$ z@i+xIMYCw;HT20z5FEB>xMPt-W%Q1S3`Ew$I<9kdOu|Da^dZAI5I~mf%8pvt0~Ilt zvRfb;1gNh@#VLh4CYKJ-#D~g)pgN=jFoaR!h2#jNL=DRUeKRF@sL{vW>3*W2k0pXYiqb~TLzIQHdq70N-~DF)(X*S6Kk-mB!HJrZ$k3lQF|lfOZD|;Y11K1vt!t#>NENU#JG+rn zfeXP8ucn)uG)(?-pGHj6l&7nK82cOsaC1?fe{wxe<8qp#e6)Lh_()EJ4DsPb`Siu^ zqy4kVSJ=OQ+}_{z_dm1w7mxjyZ{|89prN^k`@Z$rz(wTw%iV{+|9ktJ>HPI$U){+@ z5k4FaH)(plgYDi%$4KZ8!CifK_p|@k|L4E|`aD;TfWCxQY_u(pSQyltC9@BOJsMH! zTlK9f2f26hZWw_;4%FBdBM1jsDquG@4o~60XlCF^y8DzpS~vu><`}JcjHI(mk+w1^ ztquAKr@f>xAcCvSixRp5)rEKn?W*o(UL0fg^8%{C4wj$?mh9+}Cj>$Wz%9IE0y3en zI6puagbjT~P>f3Ap%l!3U<#HwWC9ALfvY-jFhM{xb)q1TGLkk>i`Kx!M8MR~>e~_; z&IOQhLLR2DM5s79NHSmfQa{*iP=&fR87tbNVHoj?JB@N%aEpt z?qvuVeOtWFPijWJ6Imnmwovb0olTYV{`zuP_9xtG?8->YcoOO z0nIEy09(%kDnvLKfo;wSJVR^buDV%ZV75UR-7T~>DTX6O4p(&S5O6){@gO;`G!UmS zG5`x`ND#dN0fM5Uhq#8}7|1T}nA|q-9x8O{A z^0jUj;MxsZAg@)o8X(fos#XILun-{lnK~i5cLsJFiDQU36Z&FCPJr30SQt6GRyaRF zpBNj~3ItY!+=3?PO|nu{3il}j14`0R)_}|eVF|TXD-aE96S;eHl!xi%N8|DPG?VZ4 z<<$q}M?X3K_~q_+#}B_*{>vBN{oPmZUk9X{FYoHUmqVsf_>VdzzUj#Md0%4WqYbx@22tQ!$16; z{f!(it`5&%?mzxC&TW2kKEHdKPn(T2K6~XB^TU>2K7aP&W1k}La>)blCnrULx-LK( z5bok0-n&B(uzB@m(|YP^{b|E$yW#NsX1tlwFQdOq%D%&^PZ=GC@&MFfn)ZYrBT z%%}YFN0&eP=oQ~y;56Lu<&-Zk^X|pfl=Eq+-^}gq{^^T%x4+pwc-MAwbq_Njk2r60 z4;K$g>yN*8{NOTix{mq+R)zJ(9 zOA#y@ENEJaIU5V7SBmu~Q1IZYv00}TBFj&#lshtJfNif`- z@)n`lxKK!Nl9U;R$pKSrGYkXvjQ(Ui1`n?0lCV{VxmPfY@NgIayYvz@Kpc30mO;;f z9@WDlY;h2%4Ohp`&^L7nXDS7lh|KezOwGX?qAF_y5P+(Vwp9U#7;Q=cMB1FEP~~m0 z2#^kY4(t?+a0hzEc?mVQhD;=c$jC0c;(gQe3Qu>a9RuCBz=(ElLXN3xH}a4kIWdxL z!41hB0I_zUF$OWuer_Fo@ie4p?o~WpUn84vcvnL9rS&QCkV}zr^~{M7N}O0Uy;9y07w zr&0!Tw=C-lyfY~Rl36hAvKmHG-5I)5sB^EU*2pxIGzE1x28E?jO^g&+1KfHNT+}Q) zEYOCWb}nwj#%{z6umv>tK}kRuQ|>rSNWmKcQ&cCYycci5>`mR9x&*rtXIw+i?Y?y+ zqad`pdOe*{70_977LloDNtg%8fs71^h=Iq56KR;ah#rMBAy!c#(>F{hfzQnx#s{j2zEr0jL?KdZbvz`gILhIAtoLWvHGvQdh^CU0 z?3UMG*;ub$eZ0pJy)=7Vo}RE%y?+96GzyfeXB#k3+!}(5FqTAVpcIEO?{=~+3a8pP z8?L6~htCclUR_+5$zfZTr^l8^h{i=@UHJIf?>_tZdf>-#dxsy6z$G&Bh`S3JuSa8D z;o|+f^EUVJwIaWMcSI=MsgzIC#iE#H)FsGtr`zq1mX!$I}%zCw`h*)Xf-;(=ISZ72H=q^{@I0Y%P^{Pk!_{` zBp#4@Q)1SDSnjr^(cH&sl85PH8ZM4`N}Ptg8&EZ>1r=O~(HXGzd;kv6NLiyN!U}l+FOY!{p;uc+>s!wyprUoF(y|1Tv~DimYpbWQ7#&iU%gZ!!ff4W$VCbG#=e}i%DEdnaWtw2<5lZkWi9{ zI1o0#8}J4;g)=~nXaFg=5CMiePDqG$4jf%5D3A>)P#lo~R{#MpM-2o(hDd-IfB+OR zI%r^u2mlSr$QVQzK};@8l2{T$Hw|w>f)1j!c3i7ABcyFM>Hp6Pj3}Tpekj-NR-8`izd!#jjdK$b95UbS)7PJ(BkctJGAl4;dK)^6Z z6x;@a!YMIGhKDqa=q_~h!3e(%%&Ohl-n=T$_xkW~_w9EgyW{f@`qOKe zpTIC3*}%5P6F^c!MCWpqo{h(=PX%MU{cia5gXwteG22EuFUx7cZV=>>Oc!EcM~=!= zqBl{46}^zFs_ zFZ-8Y_WBg*3NW!3$ujNAAz*vFJ~=4o z!|99m`rYIxi>2s<B}a44{C z4qHx_k`R$hLVz{0b`Z*~vb2iiM2LBa`a~(kutT(1!kc3Pr05P*3fT(o7#ayw2UlZl z1q={vgP@A0j%qpK#=r~65q%>hpArNTZaskffgci`o^X2z+d&QM?tvU=wzKGA%@YA9 z+l?xKW{6WbDGM&|6#&!>tKy=r;0S`?07_vR-7u;KhdH=v?}h~K=o*oMm^^?8Kq4Hy zd4Sa(t;M!Rbpn7u=1iC{CCY-w?6}9wKpvq+90tIOXx<62Q?Rtzpb=M201X&A#7u;2 zR^3dai=P=f^rsDa1@>T<+$Bw{0PNLE38Yan^^V~>jmy%|ry+$mW6l{QIFQ94W}VR# z3>bWr1k0Af5rKDtMH0k}WF{mBaugyUfDDk4gGdv5LIsDQ2m;s|F*wuW>PqMYrrf=Q zVpfOPtVvtL0s_!I7DH1&<18y=)DuFA?FqLB=`$%3fEMR4%!kN@g`=&Ag1jRz4&@kq zVo^h2poB4mERY{GJd&7X-)0xKER+IhFy)j8fjb1TaVg`04b8klHrgJa?zhw5{!{t& z|MH@Jlcw)xOmDs!-nV>LWt-*xC){OkYS2cQ4$ zIJF#aj{RYM^Y}OaaK8PkKdotlw2$N|!}$EghX?GTi}9N${Q1wm`{HdoK{AR}SMhA% zLUJ{vSD)=KcSC!>woN(>vaU{j_r1@@?|+&KlOzx8flBGSzy1IH-~TUPJ)MHB6Ic@V zXfOatv28U2>zbH$dmVG8flDgE;JvbKXf0p^3IOWl6_jO2bxVD9L&`?rsDX_sS4-kF zI=V*$0_{2SApoo{E(Y$jtwG_4=HL-wy+zf)52pUQ0jT8*`SFyD;M$wh4(P49SSp)ku83JTL{46N8pV2R zZVjabln8CiBEZwoWTasVPDYU&GLs=PQUXv121tMjp)q^V#=!_`Gz1{P7F5u)ksumk zLg;{mj2r@#DFkq{AP54GKnVkk9#jH39FTSZRd^qizyPQ-C599LlE47KQ!;}zq`EE= z+?DefYd~6nv6c*~&ZS_0Z)-sb^krFvWz`EGV!RNPqJFlmz54YP^$5$UP3HF8qXB@V(t>1im{mGK{m)?K9m4XmKxSg8T zweMH36r%yH(oKduTLT1JgTW*t=W<>v?eg%^N9|p(-#-EU`ay?`!Z~BfmzN)YcKQ6@ ze1H4-JA8kSb3%Xj-P8H@9DnogfBj0g4}bhakA9lvZhg?TBj{Z>Uu=5~ON(ht?R?&G zGD?GPiS7Bzi|4PdcgKGE*1?Fz%(dEdGk*SJd^sk+0~mTddYT@;x%+qjr~misyD*4c zcA*Yc)|Gekus=m?0RXm*dz+9MiRoIG}F3-=X-yFy;O76eFa3v?qo=va_Pj5VRO z)+i(=*RrSOLG?@~bli)sHXTWkcO1wdL=2|DzBw9Ojl4r@zz`7SVyMw!GiMXY<|>+q zH?tk(X!!ykzjg!%^l>M5_f4F7I1>OUyJD)3O}nWbFM==j4m`5frsJvkpX$boWVE|1ei|6aS{XeP*fr^vIdj`2qAkvD-{<64IK~w zor$)&50^p=?gR+wGOVSfHK*7TMM*yQT8L)zokhw?jh%oU$i#|2VaBi(p|IUG9e@OA z2xEXrI9l0fxQ%sZNPsJXcvO~w=Oq|`C$lr}rZOmBaUL_}AOX%5{1PO>8-x<<&~Af{ z;0z8F2vmSktQqx)3qXR*2tD!+0{}B}LSSb@P+$lpfCvl<0&|ES=-}X9h#CeMPT@TW z19lWEN)BHsK*A6JtST6U83qc{n8|vSoC9YTQXoe&L|jhFM8MsfC)^a7L0noUn74pX z@+lYYjeKG^O2FDE2EqgB8BtCxMb-)=WOpVaN;Cog28Z~o%1WBPd755uWgaUkBBZSzU#0~x>;1l;Ely zFW>&=n|HlGOXJqw4HvSzmaFUhY5G$izP+n`-MKy0B%#c|c;9~ZZ-4Wnj~`F7-=Alr z%XdLT8CPBBH7?7P!5)_HIPLOv-tM-G{Uzw#CohhN9QyV>&c?&Y&|#RyS1+z!y%7C6 zuyns~%deN=Cx81N{_Rg+b8If)!CMgm^Lp+j?Hn3{X4(yd6SJj+!&n6G7r&Um+N%43 zwt%37ixv||0$>y#KszQ900K8Bu?!N#+ASk`LP^l(DEm0C)LN7sMla-s#W8ctU>dH- z;%ZJ9Sv)e)3Xo9G<_OeDQeZ+|k#`P;sL)+YA*3)snoys@cVWeaslGS3Nin-A4p6rO z4WOPYhHt?T00v$}fu+T8#AWM%iA(5;YK}-?7!r98x>?S&IY@QOP`AJxYzrln2Z|d2 z6o3dyh(gqZk|z*w_OntlNQl*HAZtM8<-N<^Z8pxXbKf)6FhKSSG9 zEa(@K9w@>9T!>b-K~S5ss7X*r?~Z_!y>H-Ar%`NiNbKP{3ui4y#&Zkayz zCy6xdgo{&dB0Cw0xF8K2cLoWO0oQ;6zB!Hn3m}Fp{3@A z3ByKFA{Ro%oV)90)Kiu`NfehYoI{|Ltu+*$%iz;s4&7(c20~#91|9?Bf|Rl()W+q~ z6wptK7_tEcwtXm|En(e}D4g;oUzqrUx(zC91${^P~^t6_U1rJjM#PyJr^t8mOd6p+j*dcA!( zzq>uX`{wTS=6JkvVQRWpX{E!(D}CAKW$6f))NoGiDQ}1_xkwV z7f<)Et*&m|Pmg`+ZC>iO!Z@0@v>P+tM#R2U7p^33H$xsFMh7~@3xAkCsiHB!*Ce-e!P%Be~n)} zY`3@D+qZAuJ%01XU!NN64_Dv&=jZWzcWu0DS8s3Y9J<=+u)Ffi7Mpo>a4A=8+>AaW+(m|VsL)R1$8 ziZ-VlyDZ@V5(qAdA^=c~kqKxF^rnhk11JC-b1()umeHF*-)swPCVfS4MIoGITc(H}#e3SEv3|1)D7^y5)*d9i@_@%Hem+gh`DAJ#*u1-qVSU-oOetpD zPq`!*MN>))nh2z{z=5nnDkxLLttF0bCW1>u*`arj5`G4ASSiv3WpY)AtYJxADTk6` zLLV#wwOe0#4aWoBf6E}Gn6M!g2q8yzv?z!JBN-IxbKpWj;F7m89+lpA_^Q33aKq> z3t9&ahcqH{PB=*s1_~C)d9XYY0JJ{r#ofh$A)qUG^Z+om*vHCs%UM6Um68J+(!fAGza7U4tn|j;AI=Y7= zVBkJQ(^#yx=*<Sp@j)r*VIpM`d&tGn;sw7HF!)A90>$3YT7Pp|*+&uOt|AAbLM zJ%KGxufKhId+uB9x?Ftx>EV+PPv3p9J)Q5rxqtKJS8br-aLBaFoNJw_VG0ma3gbNS zl!V5+-~1|$^y<@(g>rG$^`1R{@9@&MzL_T)df>&&XM9t3#~nP?tv~kDyKU=F>n(x9 z25(>g+_(JrO?~~)uJ)G{mh$y)cQ=cqP3o^3HX-`i=0 z{mXLr{Bx6~*Y)A>=(ABXt<|&IgLtnGrkY3ryi@ z0G5dG+I(A0DWW@u8nah{1TN4KTSr3zq7;;}mt8*`!h;=vDvG-h!P&=swAEr^N+1X< zlsLSz8iO(#VF03}j6?C-?7Z2s_*NYZoWmU2;xGU^k3m?IHwHjlQ5%F;+xq=|4CJP^ zYV8$d&pE(52!mVN31(W0M8Xsvn3*_V6anjuWt6V@@jSD8ZPlR*5XkPlowRqeTyw*6 z$*#E+Y&IM?dI6K`&tCE6{%R`L&epldjQJ2A7A`|fN7(Q8T$qRApxu}ig#m{kN{Yby z0U?DXj1I}2B!V2oFau}E?pB$!Cn0sD0!Zu)Nys|jOzO5gKqXlkTlJ8N#-ULLE6f5~ zI3p2Oa74I81V$DI^{{cY6hzj>scSBGDv4!JFPU}Byl*J^45V1Kz2E>R!W$7jo1SMN?=!H$5gCp zjH^asYu=3G6qekKB-{b?m~hrLMSzNNB5$VEC^P`NDl#jbz{MbNc`9R(-A*V3ij((5XYZiZC$aNzvAg=@Q?l*x+uOOKNaXR^Rhh+ zPMhKYyLLMN!(X3Hbe`|q(wDg#kOVjtBz{_-v=xkkQGfLP-~F9`_QRV3eE)7ZFOSli zr5>x(C8Jz%G`!n>{arih^6S)Yeo~NRcm3lZ{odQR@87=t78Wstu_T=PRHTKgS(t)x z9Dy{L5?jy2L((kBzlEwsJrQhklwIDjb}a~q!7PX!l-N2jV1-C4utb2kg98@?W~%6f zE>3CiSP>@E6>%55K<@wof@p-UkQlH!h`<^^ya8nObH`l)6%D33RXYtSunaB*iikDZllBa$AU=^_Lz-Z|V^f><*k;5MhNKFd z44KWLHRvafE6|()hQid(4pbC%!1iFNu%?0}kElfoFDrMM~ z<~-p#JMC;~YwhQ!wQ}mzDI`=F)-;Zo(NAvfh&Jpbwu)1ZRX1`$HwXH)*=Xnjx ziV#pl(!*8wZAOjASu|oyk`1%qe@gQ&ynRJmyuKAQnSI zB1{P2p~y`wnbFABkneT6rnXc80&^vXLzRs?fUsAyCZuhnD?`jA6y``u34F7lL>%9S^)<@0Na2fToC}mF~Vd*6ePiDp~g9>VmKle%m{4@C=M2&5(1DVqr-3Q2kVWQ zTnoU$kR4Kum0)z1yta-k3a*_M!Xt)I8YXv&Fk?w^oMS!J3oaPqSFuqpZaYzZF5ym_b(35CA(Y+?{}=UJiG_|QE$7|)Q4$I1Dw@K?!NfDPhS1e^PB6p zclScD8KaZzD35u6e5vc(^SrK&Gyy<9qV#zQm0ooBe0L+oA9x4-_`{zZp6B1Wd~HA4 zJ$!qyym|kh{_2a1fAothe)(_a7eD#Y_-Iex@~?mS_RY8F)BPOBtL4qZDZsW)lvGUWL6A?svH^{?xmf zT@5ns#g=uqn~*G_27u#08OhcdOZ4U#Oe7SF48RgVn8F*P;I_e(An3P3d$a~@L5Pk) zfK7cY*c<{W6gpFJ7!TlGa14G7WMuHVI)U+oX24_g#rY2U0D|Po6yajq0vO&L0wG~E z3o}*f>&D2KiLtVX*w%9)^284M6eKhy*E3x(t^kw~&Kj9?)r}xcsP{e;;sWj_m&JIeb7eW`Notz}(o~X>E`UHh#V8HIw zDQJ^)wb~ZiOD4AgdlgPhq%?32y1c~gJ<=t6cdxKUP(vwoSr9V#HcLL%=%j;4Nu0(h zC81ElASVDL2=@S7T{A{-H1`gva6AQZ7=xWb1Suh5h)3i=LJB}8Y!N`<9ua_OJxJUg z00J4Kfg9LnFc5pV0ZvFOf`Tbg@j$RZP($NDaUK9b10yHcDy9TML7j}G2t*g?y<~E8 z%vu|VtGO2K0yisLY(vtIwyIE_D3xBD&pv@ujmc759|@P0wv{WJ-*L z7kYYJ+v)Pv1x1Gff)<2+j=R@ief;TvJ(NB99j06u^2C?>=aS+6yDt^bwVP~!+AnVo zjQq5oTGZU-@%>$Z$?hXt-d=n-eENU*gWY#`Q~l!M*#Git{_dN1!|wXUOmF_}X?Oh} zcf*T*-@p3xyEk*3dz16M_6CkyZ#V$COArC~wiyyyjA{A(Klg~g~aJu6qa05bdvXn*(ExVyUoiQ{{e0TnW z!pt3qeL%u--~c$!NM+Ai`obich(~hbzG}{hkP}ub7xHvZSt8|tOke@P98jx~N-j`q zkU*yhLt#+G#6|;#xvz9K=K&26F|fM`w2f4JqO{JP40#~kl(U2pnS)UTU=89hLK?Bx zC|ym$5OepQJnbDeY}FZp5HiP8!zm*UDHM4JZb=M+Lxjwj$omXP3>HJ8rp*$pt7(Na zK)=TXK;nU50N%|dVMeXq3)jaUJF1U>6uK#5vLIOjBzUCORVcM?5oxPcGF!*M4kpfS zj5Y%k6w3hT#GLck9K)2?#Sqx0l*%XmM*y8mutGbkawqsK^o=&Lz=oNISK=(LU;l$ z43E(!9s=9ak==_0XpP92i+37S{x6LV!SUAIKj)T?IIW1(rZ! zhCl#}01g)f1H$l*4nY&z1|We6V>THG(9IYCIDs3}7LWkIREQg54p#6Ip%zKNIsgp9 z4TEH|ZB-%BFdobClx$rVgM94zNFg*ZCebo^60jB` z7@Od;u9y--A;X+JlQ=|<=m-fzBZlB7z!EBukWefhk%o>N2ji-!OT<3920-f*wv#KE zbe{>vv9DI5sA2iwa2yVDeYJn~eArKEJj27A{_g&Cf4_!~`G(3~x#dOiy0A=$DBFEi z>G`m|+t#H{(_wClUp(&*_oUh2aoWAwefA0R%)RL8{_d-<)9yMQ^89dG=LcOuF7o5k z+h_Yrq<%QQ$h!-Ee0n-n2kW-sIC@`dZ8zBgdLWklQ0KSzU;pCS&F^B)RCatZI0EwV z^xa+C%Zu;-!JBVxgY0s;8V{NKqHA4!A;s2WB-p>Wy1Ljcr?Z%oh!=W1_jPJ}J#A~h z{hPlXhoAoaSNC0~$8Y2Hqi>ONs>?mxUr!h9qpRy1;D_lc!THyK7t4BY%|RT3by;_b zfuWxso?6q`H-7wV|NO)M>iN~(edhxZ(t4(JbF-T-%XPhgYWvNvL?~Uv&C8R;?;OD)n_cAl!!%GizVZ^Wo(U zx48&pbCw;DIs}=SH=Ghs4rUyJH&AM9j<5$LNZ{TG%smq^2Vq;Bu3gVj1lo$_;LVUL zMvdtjT8*wG#ZsZVI_z*gvt*<|G&3b&3`guCH_^AChOoGIhNXHAu{xcfy>2!5_BX>-@;I zNrxGkIh6CLPS{#WVVEHTtfMC_fjETlrfN;|VFkBfa;!Bdb5?OoB}zi08r6G{BF}Rd zqP|rw8Ji6rU-Kk zAaQ*dlJ!=|JJ7_fo4f0VLKqMl5ugn4z0+OEL$3+qDgMp7#l`dG{6b1f-FdTH=;oC2MB_^8g*zdv!HN13 z!ocUyU08KV>=W6^WdQ8R3U*=g7`zWY(E8|_Va&d)3R}bksRAC-WI}Yzo6<@UP*CA+PuWqFdLF?n7)IZ8IJjy(`(`FU4Sn9)((6?A2tLYAj~Vzh zzq_Aqey}cIXT45)Tb}0HH-l2Qr9HjR`_cG=!}Z0@XMZqUO^<)`pSbe!^dwoVL3O^n z{qFhvSwB@`%p@C5+qd`U?>#=d{5V~dX}C^o}`x6r@&(^%FcS@xL{rTt9 zc(sT3Z(sfRg`Mtx`S!6Rb7G??BGn@8MyPR8-C{7{Ow0Fw@B6!{)_0{GhoH9rdpaC( zp&{nP`T1dhOiqD9((U1PeE8|xH}AHGyZ$uyRx(r<@rco*w`FEBVUsejCR`S$Aj41t zSf7^Flys@B+x|E)c>zm7-a1NWL4am(kqYDX2FeJj;Q0xMUGxckb;{ricw!*X6HN&d zfp%X<9PR@PrU_c3s&L%FykaiUJz5Jngg&5=QBdzNUIZ$*b7a>6>;cN)CDXb(0Xrd> z0YN>7Cud;o(Zg_c0a#Z$9Glmw3YtuTg_5XqOPQy$q02t>kbyB5Df0C znzrd#e*D^5oHhrqEe!nraeKX$hxX_lh`@1Yu5LgyHqN8OR-q81ElG=+rb|4Q>CL+} z*GL1U4$?f36M`^rhSan!eapI@*E8lL5IOPgh`es=chU~pfFuS*41<&=78URS?7o{u z*(GXq*hK{=LXZ`7Kr5DTl0=yU9keNr?n)kkXu)DNTJP?a?-XOwio+fRDk9?j-8S%;VhkYBO4};;dQ9W(`{{EL=KJl;q=BNMVH}%bG*uhM_E9x1y zP6?R@s|_E{u&kbnIy3b&jx_9XI#L7(yhf3EQmbc-t|_S8jW8h+VbT}`kRx@^UP}arx&S+^ z-m-6%njq|m+&v9na1G*Cd z&}9fAQA7y@B#h|50WJiFu(@Z49)V#L1Q2EpwQBb*xfkJ% z8KW{`7M7Hu2vo+4gyRc}_k;}636GG1Z8b`ubAr92f+O}b@PtT^0bBqoxnOER6Es2~ zvTDKNYsieXcv$TBY1^tc45i^2@w(og){6bjT^3d5G!d_sd7cbzkp z!4LHO4?mSc5C3pGq{Dok1N7$j(fYX1;?{LrPbec9^KrM6gT=}EfaG}^EF?jOAT{^P@Usn4~x9%dtl0JR8Ha)BFOo))%m zQWrlCWu&G7b=3Vy;`Q zT!S%M!nnGAb@O2vvcWC`8Tf&(#(ux%>B@(aON-Xe+QVVHi<9C%{ZD`Xt6%locGc>s zIhigAz$0&z zN4LryFezvyR1=o%WQCA-5>JtK#2P-rwqR_LkBD=`9%w~F0O*8K;&aZJ0hsNxVS)(nzBpMtMBoDmrx zJpdTlq0798H_utXbzBPQonPCs^m$%8iiv+_ezn8s$=HX9at#!)&sM!uFhrwy~BP? z#e@fjF4Pkt@j&1Kie^aasDOL7Gspn!-T@GhwgASIAv(zcFc1WT0Dr5yCx{i`5_}72 zfDxGBf8zuYkTDwKfS^EY#E2Woz>y)`HcP|U zNp$N>9PYUF(8{$UAc8UpBCc&KJD2gI(?ChgYr#AUhzxtCL6}E`Al9=DV+5lnuvLvc zESS-EY6T%+8XynO71Dt!I09k{?Uq(FAy|-R+Z8BbG6Wu+A|PRe)986u%XMSdMW33T z9&a&Y^B@nblqHzhkpnSPL>3-|k|VQd^L0gcdwhKQ&+lvE)8jjIJxtSBic6cuG+aJg zpB_)A+oABqZhv_*jfullN=H6SQ>n{Ia{>~y^>BGPy?kl!|8agh_x0)hyRS0kd_3%j zp+b|gv#L5jU>H!{?`KO2Al zk3asw4~G|N*xqgLDJtX{vSJQ`EW1P)5R(%iavlngj1tLy_}R7S&0o_N5+Th&11pv88tS9fqd-KS>VSoKTmJrS;jT}*c1z`}E9a)Nu>MS%W z8vq&a35nR$yKhnJ-MhQ_anq+}6avi0{X}NewdqD;LKIasDo|Ib$ruLAgtc)af+RpG zVG2h9^dRSSQ6d<7C{Ss)Ys}SV1U3>B=ytaC9LNXnoV;-!T*2f=v=kl0(`Z!U{H1vSXU?iC>v_eDj@|PmqANsbtmDNn zmFOEp)YdDp^T5z$2Zs!Ti0+hv(h(i8D{ui{gD7xBYzQrwfDC$P2t-0;zzi6Xt^q0- z01kl?Xy!Qp0w>Tl0D>9@2P-llr63JXK^ahhbA&tg00U$Ic2Fln0wRtuq>cfIhA5Qs zkn$j^7|tmh8x(1eb1apo1cv!=;HmJK(Zh+5z{3JjGGP$wqu_$J?FSqt7B&(u$x|Mg z0EC!Hm_Z0|aAwp@9&9bx|Nj)>*V8s#b|2>bR@i%Y_Z^<_hA++xW`F?*P^3hKvdRbk zBYor(hq9~e1M5J+qA1a2%Vb%l!~_8#FgbkjjZe7m?%rXol5Ha; zxI1rNYP7{OLKxNUIxspBpb}x2h_^cZVC%{rv?cAlxP=ZySVLIq zSGAg$toNM3F)oqbOYS<`$8VqCtWx??JTHaTQHu6@9X1k6n#%2q!((qgpJqwR^5v(aezX4m&E>kk|LUv0JL%Uu)cBg~8S-LO} zDfj!wwmq)2q|?j!=5WW;scxfQD$hkC@59Y3Wo_4MlDXS<`-4|sesb`qv2DE*rX?{E zf_kr#$uvZ`Ti(62=jS@!e*VKRKmFm~dvUlKy_Kk`{nq-g<#<@+oEMp9$y$g+X-pI) z=T&>_x>@XFW5L}yefjVGnLfRZ$BWn&@lH2b+C?sT7B(cs%-!D3|=Ac2mM;}8VNWz)Yi`!{FM%!~LS^`soV_Put> zF$g<#U#uKozkd1S^NSa=e)?*8b$>j5{;8GaJ#H?TuOG%&-+lb;chAoizCL&FP9}4|M0cz4t*%EC<2OD}=?~oQrQeSqw8=c8}hf18^NaUe?3I$KSQ};-?q)Km3tV;RItXDf(rLAC~S1#K#5YN zv9aDI>ZCm? zGbA_Svac=?Jk#}hTR6R#znpNjS#!x#Os6^bb?ZDDU002Kw)dCI`wwzIrNT9~$-H;R zhbI)3r&SNPv0mu?1JM+-Q@v)}ZCcnaRIjd+xnU43g@#8D=Bp2vSUrs(CA9Tndt2A{ zO-F%JX>E52%{eH#4@l%rB0MSwLlmJ)AwjHZDg9%|wYHbAMN;AP*f&BD%9KtRZ=OuC znMpSvZSVQyeuacd#**5uk;s<2hIcv7T4cm}-TUXSUmWP7x5p)?!~`gV;T2*bvy+&C zVU&{Z!JNI5@ilqs%sL*7Zk;b>xW|E7mz-2LjH!FLfSgCPlC%$~C!GfIk==y@W=_K! z6A;>s3Zr%eb!7s>hlyj5P#8-((0&;yleD&VC5}c)Tc1yP?*rmAB~CD>Mnj0fGAT`~ z;#J5~;tXck8sT7ZJd24TRCojcXYb$?#DXbk1{w2&2yO zhU>*Msj)ZWB$NhKbxjyOv2>`UJ=$^L>M5ZnX;;U>*d-c9-DWNeTG){f#7t1cmC{;|LF67@Dq9Z{q^7`|KZ+^W$)ymUz1tmi}^j>9*-5@x9^YFX#tIrOf{zz``e)Icp zKmN_*Z+?Hd)Mmkp=yE(ojM!}Nb#1BJD9hoTyun{BpPx_t^DoEgsn@;oY1ee#ZnkVM z#@D|~RK(rSNt!)(-X0Ghe)d;ie`ug10Y^~vp3_W4(S{22a2j=&78D!krtrG0#HVnb z)8Sa`eQ@J^=ws2?<}o(qG)9~BWS*#GR9@~fKl=uZ!QiBs{pwwq!JM7LiN!akBX}nX z@*`rP8t2SbAqT`N;=J*gIxG=)?rcfByRwI6o2usG^*Yi_R4@j{PE4pXyt#|0QEr-)t&%NTFt-(~2CfHNTJO-^j z9ho~}dvWLW35|R{vJV6CHPb;HC!IevkU#GxF8$d9PVA$>gESBYZO|CO%*M{y4#gio zaviL0>aCwH&reV5<=b~VBiuQ-@k})56m)&67F^7S2Q6%Ch)_;E`fi0-k}$avSgA|j zLJny>?&1LwHo}q$n{$p%k2Rj(KlvYh=9O~f7SH8;+FFITG&j0G&Tp^Nbv!=k2V6e? z^n946MWC5UGh+?!J~914FUk@=LumM*L_JtJ+^3id*Nxc)mo6vA9w@9p+g&Ffk&?rA z;#>D-T_cALb$1>YNTyNAbmI~f#BSk9;A0V~5sGLorW^*LW;R6IL(H&M5T1PZnW1KK z7#$p|cOo34?ZZjLcwTfeL1W2?m4#e8MKPUW4K~0Mq(l-Sunjsv5Rrm{1SCSJh#V{g za|U@L@04a3lbS~-H>hA#3!;<}L~bNg*dTC3fS6f5I)Vuea15d_4sjYDGbpH44JQC9 zVU=4nXDdEJk{grPa5PbAV^jyoGM7aAps`w}eWV;?mn=wv%5&ctOG;@8F zaKhjW->F4I=Mg(60$I^)cBL|BXDQ*^K$cM1hf2<3g^o8P6Jx~CcA(RAUVD4KK0J-) zJ(5J*qj^G)%kwtfpC9(8=lXR0=%L^2PrKxEvZv$e{DXh=?@s>x{#AQ=`hI(#r}HuU zJl(#E=jTdczAwx9xn3Tg+h@#t8q-$B)B0rF?fS%NLU6sVhZnEs*SGVpkJB<=e)-kQ zFaG3oJ|;%5cKPs8bIg1i-W!_z#}9w_!^``R>p6e=#jB}r zTi;&ZoKvBrj`bIRO~)T*c3U3hLwmGKlH*vOr|D&U^P!%8`r-QffB8@Ui@*EJRwE0I z)+$lXDwryc_nL^_yyw0$)KQ~{^Yc*g*uzegnAQu5PRyJWXp~D_rSbPiHJ3R>XC}+aT`8Ywd+#H;66e4lj#tyD?KV=NYnL zOgh~SUP+lpYf(8w>`^!=QOF{bo9%&O`JBg9gcP)w+@c0rHIi=!=hyG#oM)Uv3#D(sz^Z+ z5JEFyqKh{NMwcm#A-Q7@*eXdvrf^{H2t%8V&2>t=M|Zm+e=5j1Mg=0s$`Wl)u$UCg zd-X1yhgW8S?J*a+N-cf}a$CR_g;EqJa5K-@)<-SJ%}Pkm6ODSH>nf5CvP(I}Vj>VY zL18Y!;UAsv5gXzL;Xx1NFG!t)K?&%@3aP{mID`|Kfd-3)a73`XAw>+9K>Pu7G*Jo4 zh@AuBjsSv~oLn3mVg{`NaA-u2kN`lLqBBh%S<4^*wzVLl-DM!oIowRBch^>0TWLB% zHsp!-G2+4_A<~|z?#NSVbxUa?3H8n*2NmXk7onk)wXQ>Nr|}Te96Hzs*x8`5529{J zy1Nk3%OR`zdRd>=zK##{IMy*w1?fsG@FQ@kL>3o}xH=o73 zzgaae;p_89tQnEFb;JufmLKtFf8^9h=70Hr{J;DU|EkwZ@5UfgnTWWM#qE9h{KvL` z;QL$bR${Eb{jEn)pbrp@tc=6SQrWg|ug~j?(-J3g(tJ8LF>SrMwBAcwJaz9i&nH7z zctqCG0>yl#e3E)~7Pb+`SGKw4;I@;&D05>&Wj%VoGVe4M^d4?R0Ut5nV7~x@mL+#T z-UQrT85?tQQ3~<3an!CVN^oNawFnK7+t}WEW0F}kQ3H_%jHr+%9*?Fe=hdA&i~D`q z*Qh;Ay^f>_;nX&s4iO(6XE3Nc8Dv}ql7cKPdV7k~jU8{(?FqL9>dAu zYe2h9DMs|wBco(~u0a;6BNCy)hh-&6xIXoi_T7H<^|tpkup4VC=iZ+s1n#4eDktUI zx?8t~e8_(F!HIK}yBFilgZ3DEpKp&tg;xhB#qOj@s9whK2u&DyM1Ou*hZP{4gPq6l zMAV2<(q*1j&$su7`u@RJ-?QiQ?Hzf+Ms^~t-4BVbL??O)QA^*tz#eqBW7Kkf95tq7Np})jbN24el;Ul`s$_QNpV=6J%LO!r;U!QldJc z1X>N*#yE(tBy$II-Ela@2%GP?ubeClwqCh+WJXa4J6uR(5@Zf^W(o*gz^gOKxI%9)Gf{`o;4-h+rTaXe{#7+Sk2{91OQ$j@GS@;AR6eA)zL4q9{u>cm< zC?ByKg$HE>f(PR0aIk4h13;8ShPX*|xn#%HBQf z%F;S!%_ypg3^o-`L5H)&)$=ZNF-eNxND&>T;M{yeN`iUB&U;06LjvzE8a}b_q_^-j zz#tad0@`U7`QCUCN1!=_sJVIUTMM$mVcBEYLJVP6GcI`p4=~fZYDojSOzSw`6EN4W zLoU1C#lE+(T;D(b`e(nS@`?nREs&8^*O_7kAHagCB}!x z>-F;H7eCuBnQ0Zj-X71^#?!~AdAY-=r_a7@zyDx+ug`5Nk9B>RZch=-jc`tU)yH4_ z=JlWbc)Gv2|K!WZ?IFi~d;7@8(`P^Y!N=#nLKj|C$W<3vp@e2r}=RC+24Kh_E+cE|EnL<-7kLjKRamBEMcc| zIsE7~OP=Ly@Bd`}!Ek@| z)qnqA{*V9cS}koz%R$G*XksTsp138v`%S*Noo{a5|Lecb5m^;$?KaXfU9UW@E3PK0 zx*X)@mTy1t^{ahsI#1){JEEe!=9|KElF;rU?U`~3J+d?P)j7iu88$CTwiq7!)eEq8 zPXe6CJ0!f62tg3R4Bf#zoJ8CVx|uk|)Y+Lcl$ff|C%$%zkx_aIE{icIyCOVNw$V9^ zJYzi3eC99@C#_7yXQzDzx7e>Cg^cKsGo^5iQRDU#uRE^q-Q37|^azf7F?>b(cNWZpxf8Er6f zonl)fQ>$%Idi(bB-O!ybip9)Ze~@YE*V_8PvQX`Yk(EY7S1(mqB{5-#+OvQ5WqkKF zMR;xggweVr@=DI6;3sd&OH#FVkvO&;v92C#l4PmGs1!9CcDq#Pbj;Cfk`&%2f}FLf zH1UbHjwNq9=-Pc|DZ!?^GO~%low|`uL%wWzf^i})C&M=A)X6urY6(Sf>p zG;;P}V$Gaw@A-UG6&2HPmWfG-jeIj%%pj=nDG0zBQJpiTIS3?agdrH=ph9sCR`~xP z0HTC&W^#|9jiH1JV?aSIxKa;S3MKXk4A2xl0*#!b)__DX5rPKwfm8`OIIC3wU~2H3 zbc~bx1!N|+vy-&$;tp-poK19R24H-m<2$~fXyXq0W1MWpo79K_eoVv>?G*cLr zx%ccVz-3mvPd%r+}S_0D~{AOp09d5%KYxbhb!gS>hSGml>N4q6P$Nu z&FKK-?fU4X4PxYXck_?_{Z}`S#`f$?ZVL`80_b?U^|(w}vZq($<3kf-~5yRDRDV3 zW&Q9x`ce)HG96w{_dovWs~-@R{P5Lp{+IvrKYy;`5-F9aE!f=01mYSLPhn~7V|)KL z2)(t8(dG=4K<7-O?}>Bo7a}jpynjn_Tig4iYVT4O6b#rT+m;p%EpAC%B$|1nl*tAs zc+BcoXJ%z5(We>;XCp*p=3b@Epw$`SW7Jc^M=$q2J`$H07FJD`B)b|LC!$2d5ET|? z0ecQkLdnxalw;pVr=%8IiHT4>72id#Pp(sR!8F5(z?`|R#7${})Qah*?|Vwor?ZZ2 z9B=c(I|CyR=OPP8;pMf|ZDeAc>28|tkNHN@ZRRtXBB~=8Ik2)bQ{_-ZHBvUY;p;<) zfZUYf!dM|}VC;e1%_ic+^~0d$y4K&ly>65|O%cpdg^5`#45Zq6i^!@e5Sn$EQ1h%d z+Hy!X@bvV%JS);+(($xC=UIwJEQ%p%Lj9O@7FwGl_5FF>VL_wzTs@@)Gs_~G3v;(k$~Y4CdTNX22O}X1OoR6p#y9LIff8hup>CYyv%-CK?USQ1}_97 z%#lV=CLqW-&&V@UaHJ8{V;fIvi%iMP!+UKk$t%^wV4*SKkVG`APg-sB)}!xWgLtU znGR&I3>fO}A-rC%b@%J_4Tjq#n3QVDb<79);h+A)&;NrTO1Xag=I!r){mt{o=WY=4 zaM!jxKYZvLjY`+;shn=h-Rp8YonHTNdig?xIFrojc>DyV_sfHi`n|zWa^Jzrkq>NynwooJk6@ zmqYpVCqJ&={LL@__0N7=b>Z^#oA0yGpZ@WW{_ID$fAmM6-sze75N(y9bo`{8(&?vv z^5S!R`Q`LUG%q|YYNI7;$7R_Fn z*qOWN7EsxDEmc^H2rKDUEuCXI#C#WrGcR|1ILfD|>GRLhCol5-l%=J%3n@*?GzdZL zV22}8L0@@N(1CPz=jd061cgIF3i=v7LkQ7bsE35N#<|I|gTH(8^zPa$I)t5u5p4H9 zw!~Qzkds9B0K&MBq{5o0(sD@o=7c=^b&Pj))HWiEr(WmWy9XUkX*wQ6*hiNlQ=TFp z2Ic+Z3Cmv|~-3Z!%}3T~atAqfMGO(QrW!IW(E z5E^~7?hqbp$cgX=8zsdsL$W9syNqrXfQ48QN^atw5=nR@8lz$=tQKP(bqoty1den?;348%<}Q7A7SKxdls@ z&^m5s z6ciZZ-k1mNJBtw1kvtfA1VykrGLu>`5vkPypr=T22-}o+Q^xgry1V0u+}CicNsHS~ zgQ~eEE+Q@U-6iIsT{ugUp*ZA&2)O_<4=&Q(Pl;5+Iw^-k`oMG;=0uYf<9H&TAcd=q zLxK-jkQa(UNrxm2CA(luMmyJ@IffFNFgkgdkf3=MCya8y_ghG&llI#3`F7Ydr$oy{ zAD&%SH7_M2e6%io07pI&&By%tPiKBVkWa4``95ql7v*Idah=nRz&?DtLyCyNkCIE{ zZ$JN|fAs0U{}1x1UjO#p`*$B6pP#oTgZx0nsL#uxue(p3S%}N!vfcYSrQ`9F6Z>2r zzemc`3#P(i`SR}j>-z@_eSG^kIQS+nhnr|Ey?X8ST3#Ig=uiLb7k~F}tsUBU^h7)@ z^KlZeEqUNrdz~ zzy8UW#}_ca{rWHevw!+e$Cj58W5lT(F)22L4knl^K7w+RBFnzH*5{GU_DLp4=Kyo> zJmr~{op?G%6?WxAyUtA_&Xv z=B6-2o}vM?dRGzz67$6k07c2s9+MMF2@@=2*nOL638ExDhAc9!M8kL%37Ha|j=0lE zH-$%k+EU$k2B(3(`f`Ffd^j?r2OKG3G?J@tBf3Qns_F&~L*1MxY>Q4_VFX8jk3Alg z$_{*g;Wiz@Fj291V$F^nj%LHU;na9qD3$%`=^$-dvRIfIjLD750=F&nc%1TlsH4{J zw@R7zO%AE^urZ{h;T*p1L)vA%G{0#Py=m@Q$oHXbMOwmIw6<`*KaTTxN)b&(rlnZ- z^+Umiq_l3sgG*+0N+Ep=2StOc2~ls%#dCvSNUQg$JEdt@0}D~&7_P&Dno|a9*P<2z zx4Jn=vSFb@gD0tWlyPzPF(S#L!&30*SpX)YNxbvGvw94jQFelgr?AICC)hBqsk=$e zQDdYLBh6jn5Mn8WtTLxaiZO^g*lQV(r zf;@|OVkZi2o|7<|G>cfq*wHsD6RffiFSkeuQUi<1Rg5VXDncMnON3acOD4V@n1>u~ zx#LjJbJS>aYV0sjD%RHFEYt#%hxXsJihLt@+MYqc_5(Jv?&V z>)P7mJ7IFWs6|o>>pa2-g@+rgx*D5}-nkmt$4!DjGD{e1o@VZA@6NhV=OAK3sC$u^ z&Yp7%2^CgHPRJ>;L=UnHkf4e4L1reIxLHI44POpIEsQlN9MCLYQ8E%R3>H2NCC3Dz zFgb90PkaorK=Pc`+(F2UxzJccIVe*woEgI-56&?L)haAV#VlxCy)~yC+@lXdLs7+* z(=Ny3G^rjFofdgD^I_3Lk-L*F3@L;J(m(|<=>&IB^&U`$v-@zL!fPOLEIbxgBHS3X_UNu{Plv4M<9-D?|gd8SVA5^W?kGVd{yTqdUl>dSG}u zDe`pl;&v(}$h{dwvXp|!Z8A-f+>??$6NAI6TcRL_N2mi}gK$u$$OM8+ESU{JAs%c20w=IK zLbdA!0B^JPMus}TZYZ2oSP8KG+9Ms?^&*)>I#;E_y{@*BWo1l)4V{KuM@&1%67`9&IqpNBrBe7d ze1$X$b??I}^APWeqU~Vp%=v!0d2yKfIDKN5Zy&$= zFbYIpryq^NZul7xRmsoa$HKJb&}<>#v{Tbu%<@IwS)} zk|?xMoR+ffmCJE|ym%kSn`2lXvGByt5AVz2$IJ%qc|Q6lnxEco_PAebdC8sg^V>K2 z_ImUBG(JA$*URmTSCrGo^@%w~t2aOV;_SX!ukz~cufDw@Sx&cqMO(k=nC2IgEvNgO z`oo(y4?FeKG4HB54PhJOj-Te!i#my~oM#;Ga#>zXx8ZrC@~X{G3G(o7|IPbvCA~b2 z$H(oNbvaD5^Zju;-k$&BEJywLbop2R>3{wEcMDBZNST|A?8oCVFx=7WN=6}r5>(Xd z6x|NfvbE-x$SUe4V9Bzt-OJQ`6%SY+qY>P^rJSqKVGQn9)f@tY=WIk`GRO<{J#zLu zv2Pq^kpV{{!bG%lz*y7?!!>irfV1bE;89mkj$VBjF$IR_qtw0YL9;V!fBNR`rC@WKdL6 znP`w9I(&|~vuMsT!^H21!9k{D&@mB&q{4I=^@ z)ZLeckun%7AZ{XT(yJ@O>!^(o!O1K%W$_lkaAMDtGskWr$v5H%VIp!T_OL8k2d9yu z4X$Q0{3+4Yx5yI(AJ{q$L8Y=x%tu6XWg0aQK}@kYUBVVh7nc($8;pr5NmvlI-~e;{ zfid~6Ny#lVBACJ;0&fgZTmuvcfPjFtU~*CkCrXGGgot1?a1P$tJai$A@X=c+Dmbg` z_yfwL8PVl}l$A&&xjEMADf3iXUwv8F*AZHiaIZnxyrmXZT5<6q>;bl7hh9_(cF1t+ zF_JFqJ<_el#+uXsPSG1OLck=UnZ46kkqY_6*x3l&g<`!R@cg{KKP^)_eY(E?j*c(qc~%nN=;K$v zKHc4&kN5B2e2aQv+=LtZdbm0FZEb_+X${}*J1VXn z4`sU&SJwReakIKRrQ>qDP=9%M`245;ak@XvAAgzj2Db+}-f~&xXgLD=p3c$Rygj`C z^?&(iNa~wpw)7>pa(1E9q^Hw5{)4q(bpokoM+)NVZ6c&<*C*q*v>ybF0??&BR8M7jk zqm59OBtoP!l5j-y&C7v=M9p#VNEAJmiS|9Rf=XxT2+fOCXJI3v+PH^D5VNCrZyas- zEcMy5rqNu9+7tAiWal9v3waN9GK3S+gtj?FSoL&6-GdsG$i%D?8K^+TTZQI`5e8ua zSM(lS7(qrD5bRhE!7jvL_N8z>^1P6bC>+NLz4JsPOa)<;Tv<|#t_1@Nj==TFDS14F z&A~wiiH1nZGT7l_CM-^>7ENg4O2 z+wri|FsAizzEhyC)h}x}7LxXG5e-sHM9ih#*v&5JP2+3m7z`TBug-q5}= zO>tPX?K432t?>eRQg`QtUjuNckbad1Hv&VpJ*H0$4abIQQgvbfJ~7Sgg~9BBNFW5aUky? z3F^!eYG496NJs=RD9%9xL2w7LhXXAn{(y3Gg5(5uE@YuETZjhCYHc4eg9Js*fO%-YV9fc~Ugy03=zno`>&| z%+wR8d1&w5^LY5s5X2HG3k`uOJUFMspf z|LGSW*1c4$-@Mz!MM`%W49bOWZg@(L9xBVtqD;MRKqHU({IKq8M}K;HNJXFDzv=55 z=_wuOX@33fU;g#uS6|byXev*S8_ATXLv%aboRczT-N(S`rRjOTdHwSI1s!i`zKQew zQ;j~$b^GS~=MNv+zJgj01Zti|jyb1SuRr=SQ)6?{-mSQEB z78d1`QI55xZ+`yYKks^bT9{p=ED%O|G`oqzM+|KI&_J z65Ext^H#4rZCATq+S6nI?wj%O1`qG++c)(1pzZ4Q+3M5w@IGJOj^__y7rgt>zk7TA z?%V5|3;F7O@L~3+j}uEXGS4b!9F0&Q3G&@FE>w|y+4ym2o(VxSFwx+$>aQGvldnb4c!Qd5L z`WVz0)}vLjY@Hn)6z&2dbEDRbiBO3;`Wj;dPk@CGQH5B{Ge{ARG3-E;MHUi;uqsH( zSu&z``U9B=hhSm~76}%T9oXHRd?!AJHTM>UTH;|sg=sjvF_9V!Am2uft<$f*y-wpYJio(A*vDb^4Ba}^Wj!+9!g4^bP_4z!1KdUZ2P>|NQX*p(smBgHAx&e$P? z021;vfv#BB;8p0vQBhZS23GGKJ#{DbGsl&Nh*pZI?$RRMZKUBXhxS3;+b}du-uk+^ zdq{g|9hfBCM~f=iNrvj!u5KLGEXW8%@NCrEU>0zq;;D!dY$SoW0ec{2;^HfCh0R|CM0SLYl?Sv8mc(4c2L`X~k5g-&D?7_^`!6jHZ zfas3yND&ht;1nPV1X4r-6Xnd!$r`f?J0b`nPJ}S;Y_(hMASWU&L}58VoXCA2l?})g z(WupM8Y;aG;tI)ri+&xQBy_U76g=OsiSkXII z7r=BXW25e=9F}sP&-Xl?+K2Do|L)^6FZ$|JFk|bH^!}%REC=;b6VB1LJRd&&;~(7r z`2P5XI{R1u_OE{Rum19zzx&y$q_?l~U5?3>dAUC(jWW`xTNzDtUfa|8eB;439wbd| z_x1Adv_6()Qe&Q9(`<+GX{+PoH@{)-nr>|8x4-x$oy&_CKeYE>nf1e~m&}86pH4TU zM)V5V<)+P_o~A?Iulwcu?>@YHsLz*S?c>|$%acFt`&z3MD)TgfzDT%R%H6X4=+pZj z-8{V7zr9Um(lKQ|8m7~iepC4N3;u#Frtt6I{txeRqCD~bc84oXM8?zWqx|qkaiFK) z{CEHO|MZ&=kJz`^A0HBPo{m!omqgd6HaaD!a0*r)Sy+~nCe`zlPfL_Nds=3boBQWn zkeC6Cgi~U3TaL6WmJgJT4hxo}5+Wr|2U7{v zC?}boa5zJXG*BW+p&Fb58R|hDv~JX$88WVj>MZ797q8bI!&bMk2f{qOnZx#4o}S;n zxk%sE(J}sj5L(DdBVsz{V48?b9e*$ymppr~efU&;&(2HsaA*iy3q%lsY+4S_?K({f z!eYG>e zS40TF&54Y&A$fGd92`{@vM37KMYKRy^Lb3CQ4N~QEKOp_)TL9pb4{n%2m-g{yD^o8 zMw!}3Y8B22YfNP{WoaEjBAT8>Lt$uD{Sw>MeP=I0>NYH-OSUDg!d2zaYPRXuz*%jCRrGV35Q7}`sUs_1ggw?Yd%8B z)psN&6BUPJcU8$j5us4CUW2G1Y^Q}IF`@2*h`YnQTO*OO1YwLkev{ebAqEb9MZ^Qd)r)xd%Lc^n-nRB zscT~O?&LY^`GC9oHP9`}#ayd`@lJg%(!o459>H?Wb)tZL&K=ey&J zPhK2vfRKk@{px3b{daG_e*bvsqMjK$N8_R@r~w#FAtn2?_)a_7_3?V<8>x!E>8OWv zJLj}swldx1_W0qqKbv2_I8g5I*N-2+ZR0YRPam(f_jUf{(|Nwzp5E(nq~UU0<}`&p zuKV5|9u9|Pxu@gVTYY*M{`ld$k8eNH-bS~5Y}>VOZ`XR+j%G{V$IRE7J^6HO% zsC4mP{_Xbe(x#b6QQOd?oZgoxC99OmU3F807o}$V@G#TZt&M8t*Nd;!AJ$|hoX|%5u+sAb zk4PL-Dr0?&OJxlq@&>!?-S&Psjl<+KMI;D!<*05k7>&|2Ow0%N&>>)s2=Q*Ia5fh= zDtx(WYdpHpZHbM%$KJ_1d+>1C9#NlJGQaOhpo75E6iJ0L zn1T_Qi3r+U7!0t49D^XHRyzXb>dWNAohHjA8o50MTymyiP$7o1K?0n%5m&*_e|5dK z(K4ll#YbvmA%lme#4$J{g^)T&q*e~&`+Nk0(@cBg za4HKhhV=nupVU8c#AM*@BDOe-Bk>`RmV2VC8Qut6FG(TXAGx;>3vYM>q#c1R*XQgG0h2oFV`u#7qF86BVK(2=E9N zgp#FjMQ{jtP>=#flp`d(1#I^O1-KAXxKkLy$%lKwACR%EyR3WkEOSck0vhIhDxNbL zkM6KBMjs@-h3)I8qdP5Gn0Q%oa!PIz6qU7JsY6)Md(gr1Zu zcVa^(3=fK61`ObSN8#YnHYvF|1<@S~3y2 zDuLG8u{RrL9ivy!`FwXScSrd8?)P6`_i;+?h$Z!2*HPcSOOg-EAw{lr^U(P)op0_$ zE3DPW%ZK0nZheM#X;;}V_3rh{`#=9A2_5yY%!iWZHm;0}HB4%%vBigUUlM84SjY2v zd6?3I@sU`)jmw+wFfk>1^WD4JqxX-?&1bjsrzCbb*)kv6n@exI5e?rDKls7z@ul07 z#<>6N{^r%0F28@iK0RIchiCi#`SII_x1YQ|zc?OGrPaY4OmQ(%7!^RPN^Kw%q*mkD156 z_<#K8|MS0Y-CcW2szw^N(YhUGeSJSmxSpm10Z!eSJcL|RnvN$6BFTy*#W39up>BH! z+wgGl=uxY0&9>*5ln3{ZPduNhp3TfD^)b3iat;r#YqTl^o)xXaSU5Uo^c|d}LC|9= zCKSmH<~}iqv_g~_#3LYFl2`><4D;%gZa4uPZbYmMLq@m_qi{!5wk~keoA7W~ZpOxd zQ3NOqLfd0b!mLp=0>;(l6pGlcTww+oYs@pm-~ttG8_fktgPG<;I#Ze=cEFHRlv__^ zk;1$0D@9}PL^{Y_4Q&uRH|Hclm1?qHDGHNDnT8c38lk4tm(xINEk8XyfBO`jH8u05 zKGM#p*PX&Z78dMgqel3sklnPlE-C3WI;hTfhq-sl$D`GY1h|xJflEc*vr@MJ_mxD; z)?&G!LWyq;rq^#+?D5>Fr%c@n|Tu=2^&rnI>c%vlkO@GW_k$WNEu;4 z0uheEq<{rc&`MBnLR2ITG=y*x!Sei#@c(W|bjV22T zrpfK%J;M(e2zNvfU!zxsgd0W;4jwFQ;VSDRTr+}NZ(A*S<`iBnQz5j-tcPQv?7K=s zOfUHLZ9095cKQC_{-PU8yG$j|i*-Ao=WE zeQqBgE+b1yB`4oKp&3&eQ3S|6=;#{Wt&Szy9z3nT)E` zM=HytIG^)rKCzZstq9H2q!t%eB~L2LTx=8%qiE@ns8<`#jya*MRgrp-z<3JMJYpVg zY*!Dj<{WcSO3usv5(IB3GntYOWrv;^%xqMe)D63FQ(T|1 zRfLhcc!y_~LBhna?z9i@7j_2(G~kZDM^DvN3EnQ<1wr5b{==oZGxD(n49SSR2l6cF z7BN`CX(BNaB6gn2EZDnT*4=CMVa~%*Bbc z?CXBW#Z9fp0QeLopP#&Qq%;7QwCK5TI_Vtl1aFMq!?%$%cpB^`UwSq-vltbLIYcwU zX@Fr~dz8d^NE~BW3b!dlhS;D!ID*+FmxRgItKke$P#y!Bdh~7-ZiPrig-H@}Y?X46 zNe)GQWIqI!Ba7%*6OH!xn0chpGeh=XBc8XVciydI?0S^iGj-Q2p6^Jz`p%@pcL9o& z96K36?lOadSVM$Hht*&qzXCf^0&2vS5Hy@f!6o1x2x1@yEgs<5Jd}J24@VFxz%k$w z&KXR>K~e}A$N~#0Br8Q?Z;%`i8kMMl7)0zG&OxTZxgk{=9FrX8zIRd)5az7OSea8M zAv+{aX^q{4dK-3-SV}NgM;}a98;V!2d#4s;&z*!s9nLOr31woA7&6>R#E&E%-34wm zlQ4@qb*>lV+63q-iGo4u!ZTAsQev_5Ck7!74{|O{rT4*! znZ-Bz`fuL8`uxk}2`OmNay+@lR0?}f7jL_a`t@{kD#z(&K0R%Z7kcL7*~e(q(B}QS zceb?GpZx@>4eQU}zWes)|6Lt4Hl}(lhx-p-f4|lK^z>o0?fm)j#gBgU>Ia{`nD=S@ z?VGP2-tU)ZUr%@ELG#l^-@IM>_Tf+e-XH(@pZ&=Xe*D>TSNcA5^gZe`r6?4qb17q* z#a0V0x+vz?Bg1O@^*{M%A09X@iyu!^5)lw`e7)TMy+6JAkAC{_xBuCH^S}G~`;U8q zLNoTKZXw>4*U8O>K0j|T$ti1V9i?R2$W!8|l{H1<*0y{j$NRHJ)8nLv1sfa2L=$uH z7|zNIYZq9bdT7*iK3?mvK;N(X!-IHB%S6M&_C6gw5ST^{6B7aqj?RxYIulhA2~I!Ncx&!#OhGnSyBFG5?_*R7 zSPYOGnnz>D3M|pD+L{oPxhXkL&_ubRHVTAr05P4A;Rz8Kq2X$+lEDM)5w&}F<|zum zFF^;>BgRC_3+RltkuXHrsncxLX*5`+y@y3;G8(K1DcCu}K3wbXpRgV#vC%JUH~^6V z$Z+dIfcy*wsO z?jBqagH#)p;+;j;R$WITi)P?_oIEqrq#-#rbKi4VCYTD5fuxgyGV#rTgdYTt&5rIw zo>&&2vTL?$78SChf(s)E%u0jD$M3$9D-zqN-Zh5iBNoRvjKHrSI43JZZLlBxS&x zrESQ?H%G#yS?$y}qbM4@?ZhDib5cZwVL%5tSWv0Q+-X5~(l8Q0BQn8VDMZ+Ty1|&a zj8Nd2hEZum#j-@dC0PU*E}ERM4|sH=@aUb~l)I4GTbUOWPWwJy!-urdFJPjvVBmA`7FKdU8cTYM{*jPx!k>eHQg;^f7~8EZkBt%SGs)s zF7c@lN-50I_twxdFGZ;P!*#s~B$t~h&rkc63*w~n;l=y6E7%eSrR8ugacRT$raPoO zjmx%Kd;a?H^6u_*|M2w9)5pi}fAjpCfAcS{mj}JMUGDFfk}dH3Jlv2LIvr4$F(xA3bK?VW zSa{xj8z2AW|L3c}{>ZmS)C+yMU=LO~ob&OE)7^jg_vra=|MCC!U;p}@3*-S^(u&9GHU{g zDKl@?tX)?^(&NIYK~ehZBWMilmDr_-iEw}BWe#MlkC9RsS%ye=40j6JSO&RkCxRe` zxhaFJxq^~}P6+{KVD{Bra;N|aR06{*JGxWxwgF4DMr)-$7#^94Bskm=HoUsoi1q|4 z-k!zB7{|ySMn0T4!Yc1gf*66mdo0*{45w!$D$H!GL8xs&Zk*2;V);z-4b2N)y{7ZM zWTMG|ArnbDaNH1Q4`O?QrLaaxhfcBYVML%r!%!=HSoy^-zkWZ)cv_7J;3O2I`AG92 zPg$9hu&9Vos{4k0o9;6whm2~SdoA_ZOetiHI?QZu1Il$h#P>!48y z9<7Nx4Zl`rv;H_br^yF<8eWClbbi%s^C2lJTNlyZh9Sh2uE!NDL_hI$l{6k{`**uB_D-okW5 zg1M4*nlR1mv{kZ{U>peDcgdF0Avz?4y`@C#J$q~Fl#eaX@CyvgGckzZNh8>^1P>zN zU^0;a6r@biK!w9YGYAobsDTT{3a4OoiXb8%5TQuS0Sb>nB;*#fyA6sN5#dBUixSh- zB@oIGkOLYDCk~;IKqQ1yY-EjmCTc-MF}Oc({dsfSeT2toYZbFha$%wr17uJ!mlD}$ zZljs0C~4Lawxq0+J#99|W?{$M!KjrfoeCMIrg|*#*7G99-lmfF5XnSTu$Pybk2pDBIBXwms?^kal?Z)OZo$t=C zUQBnd?7Od?zI!Xvm|{=v3h524!_7yy8XxZS`TneP`S82nef6uq`S|#(=hOQ3{nNL< zd3y8V?s4|#s&e9(*%kkF3!l>_~ zK0bjtr5xV&>sqhtX5W7Plb@E5)_ZUG_^$r$7hgYp_(sqA`j7wOG~Wu2NJe)$fAae9 zJiqH z&42!%|Lyy!!aW>D+^rVeEOI^+@%>babBuL^+jecf?wi9Q)*87J%kKLeOo_X5ztqE| zI_14?4xy5qUBW4-U#itL#pqjxj0%!{j|z@Kje59s>h3a!5+!CDp+{^V z$$8N82*GIK9>K8iydck`H#0Rp1bGnmT0xyg3$N&k?H!sJGIj^=rQULCQPHj_W(T`-UIB_ortIm|nn4dFo978<>1Gs*R!y z17qU=b`Fl(ukYUX^=b@L5{%KgY0f0w=^}SWlTbHEHXwuzeLOwdP;<^|^Km&%DFi0O zCODp?4Kf!^XXeB2tPeR3hm>gh0`E5=kh5Y;OuE|IDvgs6ru*#B4z@RS(MB$Fq2%_*%`zfLETbd4!vMhm=EL-8!|^9w#*2Q z4^K7|4^j8%l(TZMvX^O|zIbuG|KWD|{+qAA^Xt>CS5Gs0>qp508DlQ0snqNAvmogHO({%rHA9+$``#zQF{i`aj;9yxc~4B~n8%)wT!xu=EN8w}uhx2- zC9Upr>)p!vWx){RXFQgy)}LF+soTWZI7J=s&3KkvbI`!V>D4*fmUfFnRv&ES&@f{o z$3)95^+&QnJSAw19!rew;W@8wNe^UeB*kbPOzybUE(h%mlZ2eYx-p|U%!3lBJ9?yv ztdTfD0tONH8kxeuu5ce9*wyn3etw`Dl}73mv|&;gb$3d~uu7x2vr=;_lroD^p2(l2 z+=^VlmHL9b%F{Q4oi@;iXPuIlx1g0?yw0C}#+9QzTg(!SH`}{H2HY$o#db%g^47#AQcD*qnvp(FrhZX zBp@5Bq?xugGK$SH_1+5i&Gjf`W_#ihNjQzMsgp>zt^-Uy6fq#MZISJ{CrwhA$8IJ* zXn-b;<~g=7@m4t(B$rV~B<7JpsHu_%HWL|jWG=he5{SZ~2@JLf9pEXvQ&MmSRi-KY z3O&MYFk{YK75xEh1P3du6A4o|<_G`*N{&uaU{~+~!5{%|gv>zD5~$(A&P<@p)+xlu zXL18E#pY3%Bl-hm5o%_}gn$!~q6+{fXjGdxkw)M5K2*dd&j*4JSN7`wo*C9UQGvOT zu(fSS&eI8a7QF{WQ0W|AJrV__gCn#dN*@;B6w&vMyt8AzUN2ol!Y{@$M$%|RgrHgudHMX+`Tmw?`}nh8 zkN4LZdrw;WZWAvy{Bmi$aQL>rCkJ}^`2Kf~PvhZoSu$?E_`+K!pA^xrPkEZ)IpwK8 ze>k4!B;~q3RE@|bwqeEda@)4&tC3HfA_oVcFk4_bM!VYH`~-`O7!CI^UVXsI)&!J zo$37I_+m+4rgloh#z79pG9ITdKer!$UaxJ`ef#a<^!ee%>+^Kn$NJIq1>|{s-+%c} z|Lb?Zzn;#o7QwrZA5o@hIW0?_Uf&%5{r`1qKmV`(_y6MUnwO$uaM)%;CkYA?#(bC# zWm=R+Z+*AK-21Q=oWlAROJU|xP7!@MvQUBcENSnS3VYPOSxTa$h)P7E`v0Q{&w6!B z(!?~;SL!Qja%o@9zWUFb)5@5p@2JC-ozy=IKFbw#@yikiYB}#0XYKp9$ zYsjpu%rl=oe8XBRBHqE}=fQf-&!6iLf9Pm(-a!faRCVpX2d`bju|A3bGBOf0gY*bw zR4 ztxMmHXpkc;ddzcN7BX7Ur`s&8;QJ2&nSc^oOu1jGgafz;xP|!Eoa^<9=`(Tm6=52% z!=-u}_J`Xt=^{fR@RXebodO2N9zJH2&QY*GIj0y8)K*9-yoHAWLS#%zfNN7E3FgQX z!lDDlS`3tAkGgq6lp{rTA#_ip_suGf1O(8bAZo4z7^{;5j|`g`pv>qCfq1Xxgo(h_ zi-0cRWH^EaP(#@_SOf-M7mqfkqA(rkBl8X&&^sv^GUMjKObihK3V}h45KclE1lg+x zu7Lvq1R#PDxnl4esIY{o0p`RJcHJaEjmjizP=?Twigf@2Mg&UC zZZ%D_NC=V)G^aElj|p2U3P?i0i6vFfJ48sfU`gN_VAsFaPk@*J-~S?+)j; zC%xo6#CVtUZMpsD|NQXf{8#_a|HuFGZ?9??x+N5^O(>9{m>nkm;=t*4xLnR3F3~na z^_-)*8Tm0!ZY?541cj8zKrI)l)v8;%)K#NG$>S7liyp*2W!djY%3*nWk3;7D1lvLZ z>(iN2&dEo{;KC$G4!Ovf0GKUN)EIiVh3O#tv~=ML!CgPU5U9 z6$m~`y{B$)URZ0K5}Z%*RQvg?E%_((uCX923A_8n{o3pr{$%#C`iITV-B-s)jTNG< z1_Zs@b+fj#r^n^fsV;;Ph>B%OQzkRd1){G8zy62se*5OUaw-hiOv(_bOpGb#jM~gm z#GHspFfeh>6PTKe^X#E>rY`BUtkh!OvDPgOlPy<@2&9B1Yg=0PNN$xS1B*AS9n`@9 zA{2wuFpaJ+fA;F-F=2|{%l(@VV%K4u>f`D`{|9K`6ixumsbFm20-=Ez%;-u;L4=5e3=n?=NN4~Q3>i=mHlP6B zMJSU63c9)*Vjv5Edl(W1N`xaYl0{$;BM_kjiV!paXoN(83Rr9PR^}a;Rn#@a<*EsVkPe|r0N9BxY<8Ei$f*yteRbT}_(22b;Fn7FPU zI5)t7^3(Y#?|1bKQLp!p-~Z@~-Dh9?Brf&+!=+(#sQFTFUwj?zb`3-1*l+jm%8oz# z#n1oQCH~?2zt+q7wovL%=5HMygZ^&+H=WiH@Dj#{mJ~xFTeSp{;&V$zkPFEwn0WfR9}T4k*j30 zb=mOad;d)0vQ@iw0IebeVuD=t>e~~RiEN9A!Ml_^lrj!}xpG&)8YqK7Az9a* z;5H<*kZn^^hCr{@!Hf{rFbzFf1LmCrbqra~eS9U$TO@5>@N$JR4B6v)2s4CB^SwAg zMm%rcHB@^GLU#(P(C5-4>h=8b@v%KA;Ixw@$7ezzNL|FVZc*Cl({H|eT&PHk7|8-v zYhkI{8P{%18r{}iN!!+l8A+^OI15zk<$OC0K>%G@f>Q>9)qGIn1VJzi^Dw4|KRg1G znKuKt*ly3&2*CfyB=03FF$fu~uGox5UpKmoa9x*n!%T^3`$LR4h88nUcB?)KJ=nA=$}$NhvT!XP55AGjISds^mfJ)fGrEl+6O& z!poS?G7QjHkO6RnNI;B40Sw516ykslV1PfuK(dH|!aPR64RA&b@H6rOY{L$YJLCod zNEzIW1PB8V7|`bcMXCTPT#0hPf;?b2+6FKYd3Zr`WJkn+goJ2Iz@DfBs$3ca0G6eBb*6*IdOgg#u66Y<|m5ix^ zVdOGBe*eRFzx#DMJ{xG9pS`-ic4yEzBS}VyaC8EPYRiZdPHAhk){AXOIMOJdVVF@2f5)9dY?YW!Tg7bbV}VP(#-XBe~C)Z`XJ0-@N$KfARUB{1+wt=EK8fgU6sT z-|n}E1q`=OZ}QF8_IP{#_22G({`FUX{wKH3zFHq1pOuF{{c0~ac{Msc?Tk)Wyyyn_ z^H+X3`(aKpP(SDDHRqPj_Q(%E{PjQltM{_s?REtcFYj8XG|sepIm3@$;eYjCZl8Yp zum3N4sC6O(WDXuUk7+#!I)@2S17A+P&5`Fl;_tQ%-7HQ4TqP7}L|! zmT2FuXFNzonVCQJCk!M;n{w&ndU~XI!Nbnch;v&c%g*ersI9{=2x*34yTY8RAqb~+ zL!M<02PTgQcgUhwH3;SihSe}3z+m;BB|Ax2Ky63{We5#P;OOk;gU~fOE2r!&^5E-~ z(zzj^Ue{}@?X*@dSv1ejL{}~w3Iztinqa67sb1VgZF39oib@tm+LIDvtA^}78Ght6 z_F;4H+8?cM;We`MXz8KK;_0w~q_`}0nC0X5F+b~Vt=CWWVL6?*v6P%SjdMTuv-0xc zbZz9rIHk@&Ik!Z}gvx=7SZlw1{pQkz#?)IQbr4M;*j7ntE~9$C7$DhoS%+crda2%a zd+7=w2)&m54aatRkIn{g%{<@|uU#2$2GO2xNrKy@YN7C7>fN0ffMy4xvNKjD9laMFa%WVN*h7~%}ES}NTUK4 zMB6GV3U*;H|dfFtE2xh8=c-qCF_LO9&%VXMk%(Gj56w62>;wgqzXQ^0wnlo$sb<`=g&hoAgX zOdnp?YrCjjz`2b#;>|RV#~nZae4aI?7xnZ*Z%s@E)8)D{!fuM2XTM}?-+lZ2b@lIm z^_!P>UxaS+F|C&Ma>5Rdo(4P|b{83(`WQg;)nMS7u|pMBjCa6Z=W7z)pi^> zjmMStPygu~PM6QV`jgN9$=8SJpOjZ5Z7G@X@BfDFxEpyq5F03tJ=UB??d>|>S$}Vr zbbj;kxBu_|KrKzrbJ@+O$8Jbvyeh!%-BSd)rJ-Fj=9vln0}JkBMZmk4oW+EfQ3 zm-X82lD5S%S1U0ckJoq3gFH3AB?=~YQkBAhX>=uWun9=BRwf4IDP(^ZyTrrqR+ zV=MU-@e0p3)~i`8Fgb5rs$MMN#QNfQJpd?lc`n+86*+3ZZwrKr?yt{Xnn~;&IzI7 zW_mX5O1(y!%C;$`pd=Q9g|^d@=c8kzTxQUvgI6aGb*^jgmundI7!zJ*zG?ir9FouD zq}R~KGDD7pW=2@coIn%dr8VCujX**gNXgY*IiV52b-_GR(s1_Z z5?w6?hSI@$By5s6${AOrg5l92&10tt*jrT_xS6z(1&iV;W*)*%8B9RiR8 zEb!oTBCQbuv4syP68;EsgHat7I6*WBiYOimAOscw5DCx#6Z%8Y2o?YVu>jo=nTH_| zpaCc)GcST^1OUeFRx~sZb7}09IM$k-X#%V=GOY&Q8wt8M6!gsk%Z?=i6OmF3BP2>C z7ivj_p*-ICO); z!o5QtM>IRF0COqBwqC|(&oGyK;MV={GY9gzdxq) zrltIT=7uH1ZKSXbbO^pjb;dgTD(OSug?vmSBePKmr+5k*5jS#jYr+qab-jOe0 z#KY{dA&@?;Td(E_-b_mC7hv61q#mUZP*1_*NRcHKh9v`Hu-UzLv+ePR^L_X*PuXw^ zm01cPdXmGyq66-dhcNGC*x!Jw`T$(rw!rec*B?Hd*46!X%Czamq;0*)BSFVtoWw6Z z0Y!$Phek-yL{?l{mV#FDK(L2WG1Xx|C&q@GvXrg2G~~%O8Fxszw6)r{g@7D!ev#ID z8+W>%M5rs5fx4k9^5TA7EA3Np@S=IQEA7(fW7Ma_40a73UAM?Y6_~RXGb83OR_xpn z)6L{+cwIwJP$D$JwnR=E1M(x%?7brZuoJQcAwBwXgkeQ-Fpp~unn|b!m>W9=^=L{q zf+(;uNsr9zJA~>cK89}2s*)KK_73Ar;OKQ}#f0kSfEn}@o*jqPaU>UD<^_jmC>vt| zFwaEJ5eS6nTgVYn9TR{ec8bx#fzUw_9RdS@!`;sTfN@3>M?+L2K+K?9@BrR{C`ibe z06ikG1B~da2O%&*15U^eK0wr<9N`!lVM7cC4zh4W%CH!*iX{gCZ#L#qH`ls)Xe!xU zq!hQUVA-|?DRiY|7Q#xoc(0h+s(6d5fL5fzun;a} zf^`7d7?&82ff2c20|*9Mk=5Ji*ulut0i&uBgn~zSkKnW|W}B)u9BO}Bg%>Bw5)FFu z!;6=9ub!1>`}Y0cUVb>mY=Ic&Vy{SpiM?1{(raf6}W-F(^VC!~Ehi{RcW zjU^#(@K6p%e0_o4PSe2C%W-~nxck!|t*3AQ^8fZPzx%i(%7Br* zQFBU>DClxcnwDw8u1r(|`h(Ve?8o`>5;b~wvgI-s$el$n2{n|#-6BdF(E5fpM+Yfl zDvZ85P|ujHt8=I~Q$WC&4z)k&rAg4{H43J#JaK2w=xv2EMWpUFAt&ezsaAKdk-^QB zg}NMNeS@_^xeIs68tqCsdyvy0dNB~s1N0ihj@p^I08M5OK{=R0-8>*fFzs({s2d$h zdVJbu*j*n1i*BoTUqY<*{}@N8FlUwul;C5DjWji}OKmYRZB znlJBv_~zG_OY1qXUz?{fyzb}GwHF@Pqnuj}+_2?)Y)CQoVaS=&wromqJC>aD_4*MX z!8Y8UK0W{J7BUkPWHdmBmYb?)y{;R;hLn5PN+5|w92#t}hGfo6kiy(N^`+5TbDEi9 zC}QK@u@Cz_cEoVsA$27(<{F_M*>P|eo6Pz?(v<+6JZcc3K_VWgK0(P5U4ptY=M(lD zU}MY{T~rh1m0cPu4dACfy&zR@R@knvH(0ZBCmg2G2<_ew%X+=$D3MfyNXyv4m<%gN zhEPT6p*aC{>|-vQuTO3{12CLAv9B8(GdaMz;4=Y0w1%(?6a;`6LJ%nfPj~-IU1y*ousW09;?QX+$xUfYi0riM!ZBv2;y7; z2y53vArltTEyj^Wqvw6L7JsBfSR)$>aKr6) zu#mDR03QREaOlB=n?o^L0SBgqVVCfUR$}M7XX*1_{`u`sU&Rl6qKnwhp^v9+2~4 zGVJqVxCjPE2wg6ZoKlTCKRaBuGuE`hip03Z3)uywae=a1jK`tv^<_v86K?0R0;XtG`&F1Dmk?=Qn1ZYIg&&L_qJ zZ)h#L9rLGsAIgK_f86~4{5T(9;Bc4VtaUQ1+Sk7Jhu{21KVS0g#1L=3djj8w>&<63 z!!N(s|Fb_q?7#ju|NUS771FRzGOtvOrEk$-a zBGbnUB^39LC_RBJO$uGNr*jOGG$6q%55qW3k8X_4JjSwZIiZkm3WJJS@L&-w3G5i_ zwPK!~wuep!A#vF@n+_?u=ghIh+C5)HN@znFz&xGrgGYyrg4nj;T_7>AyMZ-zN)WiN zG0eCvm>oo-8{ptFkX?dAY(q?)hnriuHNsSEejeAgPPv=;rEK1S0&HRl2;C0{=Ijc2 zB-@zWSc` zZAD&XKLe=Tjd1?xR0dMwluCCJ{KAPYt2tt}V~UL)m7h_JMBsF$mS z^dZ~;ym>VYC$pSD3ZWS~SL-Rm7%GYNsqS)dBs!fUGR({vJSM(Yg21tK>)T>Nh~|NT zYSorBO&*TAv}IiC_H0>FDU{Mm6)KE}Jq-n+l0P$B&@O?}^QZx!#JFIel3yJNQ0cOS z?ZP7{V>|Ucadfc>#G++|%#2|U0MU&S85?v^WbBWGgw_l!(&(`i-!y{r3BBNPU5WI*j~nKN7+cLdf)q`=S)&|5E(7If4=iX>z{WQdNb(1h3&%8X?IVUiBK z2Tq6`$RZHE0Rg}eaS8aN1Yv=~ZjKHC5CLrNg3uyHVh%9i0)&7D#(<6x$P#YhYfuVM zM5aK9K-35X0x$zf)XBXCARrTLphPU-0jS_YK(e$B06b0PO=H4AkhO!P9E?udToNJV z9k!;_D`3gkmNbsUo-1=s<355y1HBh8aSmw01LFpHG$T?%C{PTcgY6Kmp`!~xMyd_V z-q%K;0SJbi7MB~83n(TDmn!|J+s81W)`hIW9{hvLEy@az12I-gOyhib{*%w2{TDyS z<(oI(-G4ZLjII09Q%>$43~Ao)p3M@`G@U=(U+>epziQuBH}j{Kd`!o}@c!)w4cbcZ zF41Z=E^PB*7}vJ-`zP1vA4sx+L>c#OS(-Z~afVmVe)0Xo?{XW0y|$Hx10RO{?z!YW z**#M-0GVzLp=tG+y4}w?_WRE_Io!-;+G$^OrL80;Ib1)!9oGwVeg5JXr{$@|<$C>e zyZb8d_WPU9ZwCGB`ORm$%=M%JHcbAXP566FYbNClu=G*f2um6X?_-{YdN}-z!J)6pSpzG4Y^HAIr z0A*k7=_2NmSgqMstl2nl-TZnzAAuH#gP=?^Y?nw@J*Il$-DIs9W8G?Kp)qr2gn)=7 z;KN9^fGf_&cIt49lwx~Y38-E_7Ah^wBhr`xyqPy2;aW5I2=Wlj=v%kL0k@AHK-gGD z%f=nunwFAH(H)HaIC@(n#4Q4i&aN{-9)KE|dmacXC<6__CmcM*TmsRyjOW&~A8F9z z20qgo7}gip@RTG7B{H!K0jDUb;9w4tlb6{H83Tv_3YMi|iU=%6Fy`o?g)-(;APrn7 z(lJ9vMjkS7HgEpJ59VN!Iu#!PIbmO=jIc|23x^eqfl{=q+4%AC`(OWX={96Y#@M{& zY1Y~iXY!T?A8>!^1~3RAQcYZlvP6Z#I*ep11(Mmim?)W;4EsX3s6igr+SARm@C71) zq>TI&$T`NOG4bwjgn|$E=kA{KfMjG1a6sY!Hw(~!857EGdE(u(JkRiMBOBbugy-l* z$H|*Q9wQChH!uodpdLz{f>0xza`Qz(%{hP_ELhOgy)Y^P1twMmp_C@xHbWj9o3_R{ zcE+-K&zUjDZas~* zp386$I+1{IjEI&B zZA&!jJ#UKuPvvI3{p!!|e)-whe{=tjpFVtiy`9fqsX&0R$dCxe-ODjb><(&M|8QM% z;aayP(ma=OKlr)qrsez*7^gHc=WT^^eN4IR_s_P=bzM(oyhTad>6`|}+Q%bgFq z$NLZe_W%C3KYZ+j3CE0p)7`waEpSRgxGjxx7mKAw&z9>jO_f@YN&P&KBO;k;29eRC z8!FJi1JOmWqdwDsnvsr@3U0UG)@jcxOAD5 z)t~{8u(@P|V1!2E2>>JMlLI&fU?vYz3&;+_t11PBLD@mAZW-BQpfGmI?3ai_t3^p@ zn`4I5$Q7FFu$!r=SLh?GXJIe{vJ7`bpUI91e3|4~+r$BTX?%YmLzJO{7 zjfrsD!T8d=iXnJMnQ_cPk}Mlvr3|!x4$=JXF7-2}KrXi2(-Zk_4~roz?vd2{s4AIh zDte^?7+W8v*xE+vvb_J*-@N}AwE8CAF{VtpZ5vYzT~=s=A0maVjUw4#(ijuDb|P{h zBrGW7?CS^BUTvJn5jk{9NFdjHpN?bEb|nN%-s&VH4cqncYP|2ZJbc){d>IbHTqpsv zS0!tk<;``y-`Y=%FwYad8RmWMh)OvFI7u~RVIoyTZ#V$BB_h^{=;1&>oSGt2vc*vy z1_7C9eSnhGGjiAE%wr})^p-e_ZcUHHYBy(zjw9j5nw*9E$!UzfDk5iOJ-N#tIivuG zUWEc}g`_|`HpDszo>T_ePk6O#W(+xJSdpVTFzOj2aQzT>BgW_!4iHvxm;fesK{QGh zcmr^TWZ-TwB73NiV5o%`qy`p15deS#_$hDz4*+-Qo{!M`rg>xoN)bc&85ofg5J0$x zATnYPWbi%G3O+(~^d5{5>X8r}BhVbEB4RjFbO0A527qpY$!Tz{ktzJrV8{JxDU-pj zM};7)psoldJSzx&#a(Qt{pxD@+4*_3*GjGEeNAAvLE7CD0lm4O#8(Sib&h_vc^b^Y^FU z+`s$qULQACXGVu&2FWphc_`14PG!jb^v&A_UbeLnnnjLI0~Q@r-F>MYZjOcJwk@w4 zaoNpE+xoOFYmE$ieWVzyJ7P@p7^hvtr&t%$(!7>&XV-0`Hs+La$@>Gmf2T`hL1Fpf z!`qxkM}oQVJV%ltPid^$*Sg;OwXVwrIi-1bd3t>R?#Y|U7>8FMZ=e6Nz5MC#K77j< zcP~HNzuF)BwnH6xPH@JQ;p!x$$)jbv^oJiT|KqRe=FU8p+OKckKfU|#>DzB3Powzd zDtyS(K7IC+7v;}~DqqKT{oDWkfBd`eN#+qMkzn-drb8xZ)*w<&f{qo7;EHOR&bHl5 z`|ENU1Xt}MERLZr+=GRjcG*uIVt1&^g~kE1p?kaZ0tD0wGReq-Bm)8@wwPYl?J>;j zhFiic5H6CjnK0V9!cKAmbBd0_keaUo6Y1hmBmrm;5TJ(d0&C+zR)z7ZF{1!=^=-2` zp{|g`5h=(^AflrH0D^fiInL!rc`5(T4-1IX%3?VWh90M_u#e1~*twC_t~p z&!MD|&^4rFA2-Kj<_RiE!hWeZqn@{hE#l$(_pcwZc4X$D!~|}AYQK__v(mv#j#}RPv^+9NY=+%uNO!I-W~F~ zgn}0Y*I~%A+WmQ%u%=;`Br#)2BZRu_C<_%VnUf%xR~#}lFf7$6B;t4%rAcIDh)Xdu1r{@?g`bL<>IW*7++$G_rw4;8ugoZ-U37Shzwvgk6_hYvh zO7wv6&g=xmwgAMQIK0i7d1Svxziu%os|*M34KL?v0YnboObB{YAr5Gq&><44bKf8r z6r+qtfMSRqGQ!NTHSi%202qWp4FJ&^pagjYk)#M_4=01TL0Az7LqbU0n?sD5BLFa? zXv9bW5CNcG5;P192xegCH6nX7q=*25X3m5)A`u`U0uW+HaDXk~KmDE0wrJaietfP=jH{1ECIsq$E^i(OZ6+8NJ49AMzu+qF5Fn|@Mn-q(8m@Vb5T`tqOtDmC681(!=1 zhUc&H?Tf>!|HIwQJjmYffBV<}^I!a-n&GB-mxmtIx+#WXxDul^?VD57df6y-ho;pZ z9=3vD+Xg{L&gfxo-qlH$OKoIK*gt)QzDZarnNkep3GsrvjX$gM#Y)fbGxhPt(sA>fo(@l3t}-;zv*bml zOtGP_5UaPv+kzZM%htL@844%8xD*RPzg#!7*3ak5fBOCP{Z%cTdJk>Bxsh>Knf6_s zpmQ-!(obEh_S&LX>U}qdgqb?IL2pl&y0+GOmFNRQC!FU35ZPN^R+>3ujmiqt*H%xD zaR0>AZgxXIZ_&>(6hmfk<%Gm;o-DjWuPQtmRt7FHJ3DxXF&PHAY6zkM4uJ>vE23c% z>(*mn1ctMwBa2hsBF#-%slhO6ucQcB!Q7mvZM-X&@iU7cf5Ef+U5wQUT1|gaU5H=7bP{0b|;0szs05k_ZQ}i|Z8p;4w)zKQb z(ZHy{p@}V(;?mZ~D--r@p_HMnAPj3yg_CXJkP*SU^h#DqQie*7;lQDw?twrR5Y3!T z32%Z5B#odDlQ+Kotxb_R$D9>@Lj8TT{M;pzJi+w$a>lL1|H70EU0!@CD-UALj# zuRwhJlb;`c@~T}fqw}JtYMa^$p2E;A!c17o^jQ)f(kO(ub#m$M>9CWO*6os~38o`) zm`BWg16J zJEsKE!`!#Z>!Yj}T`Ph?+hBCJx~yw$+Pe4Nx9dvYm+;oBg|)UpKo~SH;it-Ow1?b7 z60cA045kplT-6f6M#zRkM6ihd^8+ zMFc`XN2+kBwJW%d6jSlC(}3^-TkDV^PO=8BXV#6hLJ3l(#|Ql88~Xm8JZN~c>sxyN z8s2`y?>_ji|Hkhh?T7dF=IWnb`-g{ark@^L6Kxn%u~J}snW&=>?{C8cqHj1>-mSy@ z&G#SQK1~)#IiZX=NJ9fJm1?wJsCZaJ0)!+1NXdhYD1{TbNM;)|@5-=tqj44o&`g76 zOjLG^(yK-0Vw!MBx(2RX2Ef9Jr`<@SY$vlwd6#w&IZqh~nt77$;66xFNE>xi+Whtq z4IwPM2^r*WxNqd3-AKd>GB^~IJqi;z;6a*UhX7=0Fb+-$$%IX9fyP8lLOH-7fR9nP zYE)<>Y(iw;h86yyh7$XX}Kqy265r6;=z>XG(g2+IE zG6Lj42h1jOq=JAz5J(saFaR@QCQxD|sK6MK2v&dyKyU}_fPladSHO3djLj!davlL`3FL?aB(^ZC%4!J2$4Sdv{ER7Lsc3=3dQxo(dt289i_; z&P;k%C);{(L+4x&Jd`{vfWh-@{e7$!mI7DQgZe4ZLyB!f(=!xA7|k3ZiE$X?A_Rak zlBZzA>8Hw{Z_D2Ejo#h%-7)v&;oDE&{`Fsd{Qe<&D3|~@EQ@hZBMws@Z;4Q*<8^zz zT!MH*gt{)^R#j%Nu_?eY;AGOb3q1HZ6LV6xx4%9 z;JTczPvcmS2aJBbe8g2^0fe08B-u;)qys;MabF=mHjacdHDL- z^wVF+*Uvif^6=Z=|Ih#V<9BU%aW@Y-5f))l z1q{Z6V05(>$*^0sB`0UUSkt~4VzoZ z2^ecgkmP6pK#knm=2}4`M$lzbOkRzwsj9J}WH5Aq@GUwv?Hfk)>gz(34FL@W7R);% zG7~6`@=VlXnrNCSiSq~wSX)e~|lk@WK4;nIA6xgz%eB{14yR_n+Vo_wk#Het-4%%{n%#G!-4#3k5w6gOG}= zV_PCq1SW{~;q7mKw>)kai%#LKJ`zL%;!w9h=+lh=psxYGK?`65HpFh~uwLW3DfrD@ zZV=tQuGekdl&n5&Nt6>Lb1ImISvb*N`iLtT9!nkpilm^+r)@s&3~C{9(#+Mzp;1S( z$O43yP5iQWE}?ZI_cH4iP-bBYnT=A8h~h{&U<>U5f%u4?SUliLvG^=uIeHUcB%y?Z zsSJ$Bk+5^Ia3uFufixFy-hhw?45e;{*-->Y!4yE!TreWRk?IOs4Et&n!~=I=4l`Ok zGGPT2F$$t0`s)lm`fCGR>!$X7v7Q{djlmikVWrzZZKo}xG6=4CnL7<3^ z0f<0BfP$JJ41hs9QTIR$LpU)CP#`LL3vdhr2E+|OA;!QQj_g-}A)+FNLqrfoCx65q z*ejX>LI{MnFeL9`XLAU3)GHuS3^|6Z0MX1<$yjUn(gKS{LKpywjRTa4B|}|(Q&SkS zbj}nOFi>yNi5z=xP_w&0&M7t2nWAn@5gJEj`e_(bZEIir@#*rzum0xUZ~n84GJSsg{EIL1&24KRr{mXOKL3o+rU`M?yH}_d=+K*di*gyelxsYAOHG4{M?{R7207gzJr;>WBR+R&BEM>})3qUX; zuy|akqBx7MV9nI5^|gfnN7v$z#*71-r`o!~^*9K6T(1i)Xr9?~xGfC<50uCKyhF)4 zWwWt$tLJSXK}@z<>FQ^Vz9e-i2okDS$AXRhd<}pIt4lRU4@NZYRjr_T2kAJ~ytA!A zNe*H_)K?&O&l@b}43(k^Xb)(b^EDNf41sKj*i}Y_z{(ih8-Oc01QT>-3rg-&^5dS; z)pJoc?;hvH*K>$?Jht5p6mtx;1yVC(*AyGm(-KRh)o|r_0(;!~ef5gqgI_hCioI8O z-TeK@J}q`pfBU+g7gx8e;Z@KEG>t7;1F%r9Hd^%Sdj96O@9xi)=1Cb_-3XFPpt~_J zQwHtVOAYAc-FTx&NkDQpFL@xz772Po8p)Q-Lk0@Kk+TdF0z;=@&@NP4)tY7C`35`r zb#sd{prq_ZOFbjscyFzCWFAWA0eGTFBU1Q2~nZfPkbhVBai>#Hy_Xd883} z#sbm|5ImmHAgCjD!8#=9ZKP!2ypjY&6aqww3E;tqT)^yPPHh8_6ugFZxdLKED%_2t z2MF*6=)nZYKq;akWb{OVfSIThIv@c$MtAK%T;?Fq2ClxIdEbiO@-mv!?`r#s+cpX$nb!5~X-d(k{bxe|&y^_2s9V{O$nT z@`t~_|M32F|8ZM=>l=gMLFfB3e&dqiEZar40B>3C?%^?a^a z+vD}(exflSzWAJbJ-E2rbhST}QPk#3N`IqO@ zY4JKgyKMvP$GdSq8%6uH_@g#@y#3|ZpFRIPTD6X+rw7T-JKRsNHiZwbUw`wrf2nv% zH@8!nz;OTa`IkTc7vykv`}siQ;q#xT-C=z8d6A$7`p>t#$>C4GUionE{QB>{`B#6@mW3FJ zhr-?ZdP3cT1V{`O?2oEz&t-@)VI)kG5n^^t2R!Vd48{dZN~JUwDnN+nL{x~XPEi^#2OVsGoB>qY|9F@WUuPVR2$ZZ}iWy2V5=rq#4EwzajjdqYLKxG%$` z&J6~Yv73cQ2X`ZiYv|^XU~AM@1~3bxj#KF=n7SE*C*PGA_T(1PoezB4csT=&Zkq*Y zLu(AZ_bh;lG(ZqAlDo478p=#O2(3s2LSXLL6=N0BxTto=%{Y7j&#B^~-sAK;^$v}p zgY^`rOI*~h{I2rO(XRWO*<}EI<+5PLc z|M(GC8P>HjW2nZpXVX@k_#%P-oVzMU#@VNWS*^SsG-@Y5twvs0tq33Y31vL z%##8p=|WBf4Ui*9gp^CS@U%mmAez&WeGOy>lK|4Nrf3=)*tY75fQSHyo|z*oB}iTa z_aqBBhlOe)?oN}$l}rK^+r4)R0;DXS)7TtRcu9bS6|zL-h78md!(w&>Br=sOD5)S3 z;@F0wEKZC`6f$5YTonWW!VM*%%uJa?5E&!^cu*xmzyxjqM3jIaFe3qwBLoDXH|!BO zLX^M>g9*2QIS?@v(TM_xkw>5zFaQl9BRW6>Q;cq=;pU(b0qmg)U}z`k&5;1zfhasY z0vzKhkcp58NdW^}%A_5oKr$z^0`6$m9grmRw&@mx0!E6|m;rjYZ#KEOZEfiWQ8$fd zwFhW~g$2P1K)D2y!;rGB_VoMHZ{F1997{*) zQnC+s*Y%-Y>M3;VQLDZF!>{vh7(P2dU)pusK72fVTHD&qDsc90fB@|Cyeo9ae6yV2 zo!2;1l}V5Dt3f8XY@vNZy8HUee4O<0)9LMfk8=6=QKtUlM?bmCH$qtwTVtUz-t1Dy z^#QM^`stf*1D5ILv+4QG;W#||C$G}l_n*Dm|KiW)FFzYz&WG`)ogeh{ah&r!$nA{N z?(V7jLI2-~6wa z6(=7{o(9Q9cH=Zoe0(;HrR?R8kU5PbaBy$bZ76~0DWOvW?4uwPRs}adUu(PeK$wFl zxrk*@y|nXv%eGQq9BnnC#EB!1f*A}Mh{J%!!l_drcPCRG73KuQv{he`(UtQGxb=2_ zRW&2qf?ZiUgkm(IZS4-#0E2pHkJQk*E1(nTrj${;HVa}f3#(zZ7YP;6#)l)ti0$Og zT|4F!b#Wy&g}_8eSbzcCfd#@5i-4h*gh=8j>}hfg&9}XI53?GT#oDqBiM{x4*Bklr z*g?ZL?T?kA>qfQlcJ+>MU7~eQfqk{Mfqm+W*{4sf)t(CMMRx~3Oyp}=A@5P8S8?sC z>C);`9}J~yl<`oJP(hj5Aq)XX0`fpY-T@PEYc7b{tOJm@GEb(R7>OOiLj(n6%4mq- z%)M}~{bZ_$U`f=oM4*~wEXQYq41}>R34FtVaW^H0wl)Mv;}`@>?V)Y6F2`M96VRa> zXXaW7S;q)RgJd)XiiThcpx{!S7KbCk>Nz_?AgE>|BGX!(rAm;4lM69p1G23!LOX#J zh?B(LsB?kv?yX}k0Y~)}A`Ewms%7o~%F(<4NFXmTHBZd06cHFP28}FER3omS9UZJ* z2>^V-+GDMNrH7l>aO|!uj65c6A_`oC8W08*#0*Fn6oC-|Xb}hw=!j4O3U~uxkU4-L z5g-6{N(2M|0qBGt4WhK(%prO+cUA~hCZl8l30#RgD1o#fWMJeA^vsE1SOHdIBv9xl z%Gm2;thHUNzPs;hgYDGTmAkI0BA%y0Aea*e)P(c2JAA$0-Fz|H!|D6$19I;H3^}vP zGmfBCbjXsVOb4&+;(mDfRhdRwJ7rwLdf%?Sp`r)KkhDgAe%Q^2`Q}!6-PT2&x8>9Q z(>oTuz4@}Ax{|`w_P0A!womuVmQ?xt_OgWU{`ALpUwySZet|~&!^`2tJl#&yG3};t z`OwzK`n&)2f9m-D`Kw=)jp^_IBaED19dCa8`Lv^9qVYJlPp9jL`?h?Lj&gG|{b=0U zr%Pk&Y|iY#>(eP;P9J66XnB9yr~S)kGEVdUr++fp+lZeI|7<>e`_0?GyZpmn{rzwL z&|7ynHxcHxZI8+u?;@38=#eytVQc}ygPJ!+ zb^2h%#Uf$pyAg zXlO8a53k-kL2&fedyB?k)nW@0%mS)iNOJdZvVfe43l1fR5&{ZAV&~Gq{IXgzt96wW z>sblS6!4SA+19mh=T6bVnumE)Xhv64vcB}**6pI}ht)5A7!X&?7ot}5N~VGCwMT@} z=48uOU%!2Ke)IHnt)VT}g~JFPbjvd4!jx2U#tdsKgE$O5jpOcsh`Fa!@<^=$CZq|R zx(BgE8R@z(0T2X%3N|3kU{=S-iJ_+@h63$u;0@K$sBc+yqzJt-=Q&|mpeY@0hFn03 zHN!Hwt;W$MWA2Tm#T7LxD=Gp$dajNIAOJcHq>ca=(+C(5ESj5i0;O@t#2%!Mlmr06 zgT+jWfj|+B49*=9%^^HoDHUIqfR)ogNQ9^rQCp&J9tbJC2L-V~T>L75j@US=wTo^w z%yl)#3_$_Wu^49{%Q2gtb64Pe_I+gbtAaI4F=Dpa*tvK)8f8^a$@@OPHed=n#EHTR|j9ruy!|O%ny{hG7H_2+17U3A9598M}euKp6~;F{3&NxF3}Z`4K5RAXLDcHw0y} z(d`m)h3wFbh6F4gCq>8p-nXj|dDAI$NU*H|;mt#X#b7+_#xm^6_3?La9v-%+7aAbA zapAO+1#EeER0q5Ic0QTWVYe?gDbMK8>(jNih$444GY!mzJKG>_0`XQarH&3s>zyJ0h|Ef)!fAOR5>u33Rmvdq`dp+e?reS;b?B~n*@x!nGaPmGCzbQRE ze7scOc0aK^^>KX4U-rw+rhUjfK>hkpo=smJKl{a>?7nz&ese?ryPx*0{Qf_@`H%mf zfB28T!fi;oWFCtGXu`D1IhZi0Qz}KK9F%A`2?l}<`xjWoOCaVk5C9WfW>{s+m@~0# zSY$fJn9^YuG|Kthh=4IICd_5r zO(J8SN)O;HeV8_qrt_lX;uM|KAv*OHtZ{QhaD=c90CVff(Sv5w9+je#N^vRx44k@F z(3MQpu7R`rl~^E03=@NT0wciMomnlI+`R+=q2x%dSH@!TM*xyMI0#{y1zniHsuQR{ z<;m)`FKy9l<=Sjn+POM*d+hqi@u>Z*e(g`c)5{Or>EUwzVY_~6y7sGg$vW-esyY&D`3f#6Wl&YmSzxn$&uj?k-Q?5wOR^qukIKXyZ!fR5G<%-Sxy0)h^&f!Uu zrzN_Wm*T1&%u~*#U|%({U;|?&U4jTow#ack2}8;$7{LrG0<3zLY;C_EwuRh#xYs;b z+jvT8WG@uf?cv@c_!*8N34)WP?%-C%9c0J>Nt_J=2q-%e$H-fNBMu2gwXXrl zMUw*d3EHU-DHze66o8S?X+)%O-v|U^b&;q&u((=I19V6kDYu|x(HbZN8Y)=l3@Ei> z4%p1WQqj^xaWmK;Tb|XR!>p84X^W;trd!`uh-g}ZMssZ>dVOTqK#Kv969^)x33z5; zMqh(Rq682?0!RTKj^Ki^0w5v*B?tv1a1TlmfyCf5F(EKA0W(Gi4+2D2hzB>t*xc>` z*ux;WV+&|u7*UWKppaG~@<@&ikN^gd(OrWRLI48+5`OjyKYP^)BjeT(b?fF0#E==u z=bapL3+@BE%niH;d6ModIb&h~rAbO^&|9q6rWgcM z<%mmUX8?vP`UZM+WK;q#kPD&*Fn}Q;YDe{@am9nUz}V2_*%E+lLS)lfjKzUXxH`O>1ny1R~&@OSTfyByKxwpKxyo)w@q7X zrWT&sx^3t4bz9~^ru}Wm`Fj1RZo@Qz_Vv21dd|3Ol+9Zr%(uJ5hGQ;wx3Tr*;txN( zIlq0#KicnK-0VKv<^4c3h1Og~pmpAj!myY9+rNK&`wxG=z?<^Z&kld~F9>yee7wH? zy*<7y`QiAJpG<^*`&Yku^UzNpPM2RV+o#hi<+^_^fS7mn?s=VdG9HAlH+b{qkCtco z@Zy*6*8hBd{=fgPhOvHn_uFs({lnk9gT*Nv!6CvZA`~&DP!$6iBnd|C;8nEe<0y&a z{sFp4tG=$poU+N#h*DVXx(ETlQtKsUIjv8iDUsSsOttWAw_Tej%6HVwTl7jL0p?(-Cd5!t9*dv9w~7S-km zshz8K0J81O9j!XJ#kPh;0;g70k-7#r&}i*sRd`cFGn#m5AvZ3Hh#r&l4qGQ8u7DMebH^{?eb|`*KIk~>*MzLre5yXWm~r8 zv|L)ia_*bebw1X4mtH8?9tT$DPU`hEeX^;B64q#W|kN;P17zKk@-A@ zj97aI6^)L`K+1MK73|tV$z;r47dtif;Du8FeK1l6oBvGQZ5RfI*EG%@H{f=G((dfiJ5Q}$BZrOM#Y-4L&5-4?Y_D} z>W|LY6Cz8m?CFsRF)P9jF(CwS0r$WR;OGI7ITR>4vO^ARjvg3*5&*!CEEEHh18cw^ zVMHf{z>MIa2GPMXySawPXnF+?2qZ8B0tA57AtAWS5H3ssm=FXIFbHIif+mMxLMjy3 zC9Vqv22w6llnI0xl2+9QX3O<@4PbAI)=49c0%0Ve=&2MLiF=p}1yM2rfVBYxM++qD z7lj#Gv#1&c-J~zbglWU>?gM*vA3AN83h)dn0b4{xSb~VHVO#_n^v)GfujrN8ID*%E z31sz<&07$LDTKD_gAbHAq>z+(x6AA64_5=CdRqLloUoYyp=e-u zeKPO3UA%84F@Q)=@eU>NxU<|j4dVps>+92Z-?sAw>!n}&y2>BE`{sl?%Z`Pf{p`=j z+Z{;bJe0Y#^GEd99+uO)_b|%*?58xa`fkOmqT{Nd=W!Qv~E%c8U_dAZ6mGy ze71h=_aC_G`fzXON3FmZ?bE$odz>#M(&`mjKv)pXdQ4E zQe+yFoO|8eGN`LtRdZBkSMRzJ<2d99tWPI5kL%i7&up#grPT$ZAv?L-x@@h3$GQ-9 zD;92O+L~H~ZmU7pMVUd2fTWEM+6)l1dvr4hWaO~O0qSZNEWY_PxeG0iF_dtN4u)e3 zR0M;;Q|{S)JW6oDK$Jj|IR-c&N3Eplf!Q+FjRo={(R9?q)KfXo2r5$dY5qU$?RNO;X zDxPr&ghWl0MSuYU=T6|zAtvvs6Qd<0&0T>|@ z2tgpX2u6qi0wN@W$Yd)(3ib#FL--@?;4Q2JsCx~N2nWo82?Br$fI=qE1w{Y_a3Ej_ zARHNi0*Hb7cIn$i&0JH&>KQR04M0JZs43{Ct#@-KDN^n z=;ob?EsuLHgfx{Ml{w|((XjST!5R@DBe%*p!I(&hIj3KI;VRAGVyS{N(&zIKfVBn# zt<@#a*XSD%%GEU(*_;Yc$LQfP_8LurL{u}3Lrgco*@Am>88XWtgJ@$=hQ@2t=3uU< zjiC!uFB!0hHLtL0hhCiq36G`#K`A3rC;&KR2@HgeEy6Hla0^622xN50Kqnn0k4mMx zh)dYkphd5%20N!9LrhRD9E=ZIl0^XSfTx&ma2_&bnWTjCy!U}16(g*}-1D(}re`Bh zBi!8NeU{-kz8vM%FUpH~f16~Otz9sWjOZ1-Tko#j;kwpV74p09?tlFh#H1D;of#ym z+Y*rFFoA^d5Dwh5Lr<9~r7SJju3H$KpFNuz2D{53=^zFwC}U!F8VjGTF_!LeK3!%hLQX@Ao!qt-bg6o#w`kE}Lq}Dv_cj8XDN1 z`tLO0kp~(XwxNjzwgCY&42u9IQe?4;tn4!*BjPsaoUhq?t@SoeKaY!}Fd7kvEm^Vg zav_}1?$oV-c;0pHqLlJTm5CXlB?V62oa>UdWT8|JZbVq6A+gXsN);3;fR#LoN<`{N zUDCV9QibP_BAiZz?iL%yoz0a(GLQqiCsE7}fQZe~=WPcMPR(F+lBR4VAZS8@6)50H zV!}vtP)ibOM#{;=xTCBDLS&L=a-vWkfB;FD6i)sIRKx|I$b0ghNt6V5QX~kH$w~wg z0}Is(E~G2xBs9(-4kCjPDI+@=M2iG5m4(W}(v-|oXcBWx(JFF3Ms(P=I%}E)aZnAX z%!-`6thxY8D~2KsLb08yD#^k^oXNRFu-$GU$Fwb|r!jKMaBu~Y_%oTqs@Eh1BB%wW zBi^#_+^WO)=uAB#lBNhd-yxNVm+$=yA4K@{)i(s(e*JxaoqYE5x6eQO<}YXZh~s#DmFKc-%LKOeq{)Q! z{P_Oi@r&*8>9j0=@zX#5=CA*@JkFP2{QCMb$LCK~xUR?YlZPx{efQ(?>GS!kcYn!7 zF}w5flBbV9yjl0xW7(&l`R%cxknDfFzu7kr|E%o)IKKKn{MY9G>;K#T_y7KX`S^P~ zn{h4Bbz#D?YI!;@UvAs7z=1_6Q#fNGl7;-p&IyYNM8$3A;Bs2CEL4PCYD_abUhZ_5 z%+BAvQop~A7&!_6p=TSaavNU*lZNv0cC^0o=xsXP)BXJqjj zlVam#)Ad}qwe#cY@!NV@+QZ{%J)a+Vd;hf7?cwqH;aMKuJ)VF1&2p;eQ=H}jLLM(T zkP&(CxbF$~T4Onznn&C3```V-jwqysIq!yCT9(?Ai;Q_(r8EI1f~uCX*3(wkMcO%Y zO+zfFqqT6%vRY;wzGt>$(T8MPpS=5fOMff zk&&JiPQ^TwtT*^7X4HiyELjc*G_Y@yC3@$dfd`F8KTaO0LU zP-5=~wE7IjoY&X=_Og%59P?p&@7p%AmtC*d(aM$1n?9-#_t$+VJ-N%XfAzP2eLMUQ zzxhw+ciZE)Kanq_N2Wh$SYH+;fGRcmI%=^6iRH0A-tq!D^#iRtrI&aCKMJ( zrI<4s5C+qR>z#d(>%G@g^%L=|H>FL*D0@5mxNBP!EKS7C9A!Hrk`~Ss!09BI;(~(8 z(9|-MXq3>2Jj0ReJINavFiVMHZKV_FM$wopY+iLabEMBBG6_Amv)^vaDTTw7iL;#2 zBB=1*e=UenRnFFUC$*_eA(b{^XZE^LoV*O zH`a}LWK-`qSILwg|Kabx|8T^@tny;mWzFM__;E?hIg&IGQX0p|;ZyhY)rjnRJFl`A z)^U#?>ss{9cBbZ|^9*3b(bGdvkUQoAnc2yGV7Se>kfu$I#NI_7$cfo9?q`W4rq@>= zphpfr*7G*Lf4d!%fg}z?Nah$`S|phZWJG=D>+eE6H;_%!4TvlyYZ^q3BWNu#S*|&Y zIYa{JL5+Mkf;fHLIZcZXMHS8-LEsY66X8-Sm*FVxkwk2MKorwLX)5Vtz~*FG;~;Js z2hYlEDn2B6PpBZ0si>Ki1PhC&1+;P;i*TR&b;LF$176&$tdoU3QLU4u<5fd%&j!TC&8bBSO9?Bl*LB*d@N!(`^f0psAJr#op<>`=5U8wSMlmQ1@eU$Z@nmd|Q_7RNGULI5yH#;V+&Zbe7xO=f2DBci+9-cM(koP)svY9E6f} zt;_|dQ>kkpBLUEI67F1tPUk;)zkKsha>k5l&gJp=Wb@O@`t$Xhzy6!|=WoCJ^>6N< zKh>|lsSitbFQDUkFY8GomUr9fXYXXO>u>+z(|5ahy?yxL58nx`S9`M z@4x@G9WU@s;ksUw1J7H2^)TOkdCzySb3K>$|Mc6R{_Q37r`tdI`R8B!#}EJd{`cSc zh`_M0-EH)^XTK%fue%*xXxjav^Nw+3zlgu34?}vNc755$th0NDk3RRXo^wu7%Am9^ z;j^0^cld5`<3;kYaU3x^`W(Hd?}5M`$IGQ(q3L?;u;}}pZ7`FMdGC%nM|Z=lRqw}c zp4ZPe&XnUOf%^!%TyC%adb{oW5xv{)Znus+_IbbEA{;((?{T|i9E>SJZjpBoS@y-4 z6Aqkfc!?e^7KyhTsKg8qK9W;mUV59=eoA-`LWfm&)=5yt`D0$JP?N#B5quSd`x}PIdOZ< zl+Z`@j^d;gg?z+*`S_oIwZA68@%*^lUp^>nD#Af}>Pf~rIuM;hhL=Nn4Mab*%!#FbBg!LTGV3!nS5&)4d zNvk$lF=V2HgtU34hwrmEV;))14G%~JJUSt=$HLZQf+(bDIrw#Jyv?^P-9-N7qRo1iJN=e3W|H@x<`ZEfRHDskJ1 zOshXFt0>Ru`xJ_Yhwb^a)nZ=C?egjJ`E$SDk1%Ov?r%1d3N;}ON^@x_pyPh;;izRI zmS`NV52w?&Lb+Uj_@$3s%G4~x2PS>`-FGj)`48{^eEF;Y>R&!A4uNA1bbfSr*h}pQ9OOx^}~l@Wcw$1`*BRJ z1=RsLRYX{_C+00T5>0NAFd9OfNH?NtqbqZ&l)BozW1lgPz*lggZ#hfQcH zETY^<;BsC(2a}jGvCbrpuraA1C#=yitW#D=4eGa?0aZm?Na>0?Q14+*b?EYPp>BQ{ zFCw4rwts>IqDijp{OF^xylm^nMe zJ+rustcA#k!7Hae*EEqJekc)KsY=Ls%T>`HNR`oPeX??5h0u!itPk&4wVp&*k_O(G z8?g)yr$$tjGb0(>xr*ty154zLvgc`Gk{G*@cje#w<3E0XRj#ay)C~+rUEXe&{nN#Q zOH?D&lagu<%1V+LLqbY~*9A(=DOx(AJhdnx?%)v-Jj|3x+md8W*8(S5!A6>fnETjY zj&V1qhZ@)Qaak0#Kr&SGL}Z!5&PHN=Q|Yz1W69bezB^xn$|9*ssaxYMxYUG6IT6BQ zjAUtq=|qJ=BAyxv4NEXw6T-}>0^)+CX{(tAiJ^Mv)FopVHdH-^nPq^d5Hb^0REe)C zi^n}nRxFUvoD)77L@C0>ERY*cb0+Z(b-_GEW{J_NPA{w^hYi$BNzjPGLb0^jdzRv) zGb|Y?&j=&b>^DTCoXJZ@CKHm81V>7PDoBYz(9E4;A>WZb1IV4?=0T|)=|mecGAmI_ z1XwaFaweLnvVeF4aS}KQB*e_Laty=-FAM`Lk{C=W$Tvy@I%uX7A$jmI_=w?BHEPw` zaL)ovsZ2B@4MN8Ikr;D=b9I^%5;+8wiOlJgbc?uPT?a}=_nH~!#KGg9!#$C6j|gf66&G0wD$_t5 z$HCQyd5`_mz;U_8Jh(Ew`^LXIGg_!|96rT72DEPN;r+6mPOY-vZ|QXX;WN%Er?ZGB zRcD%ewHA_cx{DN7~`(yXCE}3vwR6y6!LEefrh!`t6vv+w|+a$G+dEef8;& z{qv`P+`egl_WqymKfdlCKk`{bVII5?sjctM_V&8}@bdQKt(5g7wLY~)mQVlicdtKw zKMS=!mUaF1oAtl=YW>S?T^_d#T(8$({O)@y5^wjie>$(@`KRxzW;Q^v)&wsW3ZaqI>2iy z!@3K)IZf;LD{T}_f>eaC)Qyut=96NS+D6pw2XP^Rd4@{#A*DdX0AVjun36@bhjPIT z=)o32-7>vjY~H;(T7^`aCT2E_9DNIzA z5;=i!-p(nGq!Bv%%~Oai6Kf4p6i+f0jOBT$ja278y!YV|B)RdKgQ&^#`zJ3;AM7A1m8W`V9D>44b~uyaWtGiQKuDIOpc;Vwx`JOjC;J0;CoM!2VCsC6e5&Z!dE-P%$Ba;?o7aS#)9z#6g;LZ2=%EoNctIb$HX z0iksd&=L9iHnrrOyKgCl%@2yhh`kq&VM0O06H_V|mNY62n#>JgFaZg6q@XGhl0i`f zGt!WE2onp_N5(6H7qRh2qD!_>WT_J_YAS%mP_B zof4eRaicKABp0OQoSBngaA%rM(_Q6$>~ZuxG_~YX7cJAtizJhY(x$ndR76?M%c-KQ zN*d&GjgXsLjp)fClZkjvsVjP~;|@AZN=8qcN`>?qbS60vlLKi>#Hz9vUnL!5B9bW> z8|7VxQG%wCsq}lzV){hKRT(5Fwux?GRZF4DsM~s~i%|5Wb=jG&x3}wUxB}}}s*KxM zpDRb(zrSAlv{;DeCabpP{KdI$>#{xPv3DQESHE6HCv(rkMp~qRLpk9lEMs=JIfh@a zH%b;@^{7n}av$Tk+5L0B{Qkr7_Hw^}mMu>2|Mv1jzrOupeRpcUe*Wd}#(tF37rLxu zM#NI8y^Y(|s64G&6~*q~*}i-4mzTHY`RiYPdY$?F=fr>gsQ=|xUp_6BxY&OA^@rED zw~xv4;fLG(4}ZA)=D)YwA9VZ<4|acd`^SI%Km8B?*T4V!w|N~%cXX373%pfHAtGKD z)>`XVTM&5Fpn8lHH{>A_uwxdI*we@z^L|%Q5m`Vg!5bHwM$iQ%CdVv{f-Kayg!euA zb=+~k-^`7XGn@cB?iHaieRw^W*~4a+?LoL_(CjTUIHlIssfZ;HJ8kQoQSGpMy6+uf zwcJ&2H~sYaK5jOFo4HdC(lNS?p7d}NC5!=3F%Gk7^*G2ay;8U@YigBP0E1TIU^j|P zaafA9L{KoJ1DQ(=?8zV?#i*Xh1|wAfU2A13kE+Dm!hO(sE+a^ULCiym@c6*gof95l zVP0uDfe6io2`WL7lPGkOW>Azu*+8D*2~W)+3~e8N{o@}lL-rAV=fpAQ=i4r|L<)r| ziFXkSFZBov*JE0mucwpLR@-9Np*HGPpB^{uZ?BysY>ABhHhXX_nC5|vwI`(3wrwd( zu%K8E=0LKjR2(BFrnEe0#2_2YvVXX#sw@wOY0=ZVsxrrzUSwsBe&1&)VN^HoB2t5u zh$Tuu(iW}>w5&o=b<63*Scp7*MHf8oV6| z^`~oTzLQBkuP>i|y!hPf!}lNg_x~S#`PcvR<&VD|c>2x1`ZxdG|M7Q!_xn1*e5$*E zHi@xNw2Vl12IG!7-CZOygE!^YR;?umg)J{h|7A48B)qBrK)HR}~2CXUpQ&q~-Qn)T+Qxy+e_MW=71W4+=WA9$2I@Pi)owBuM z6eZ@e$|-`w9S!}BQkk{Z!Wb&eYh^0>_ztYYDM(!_X|9XbRKMQSj;6^R%Tg%VZ(}#N zG})FoJ!ia8`0PDV7E$I4o(_lrzXc&SP@!YH;<; zEAo_B2oKK0HY@2cg^8Q7XWEuXn8K$YHQ46>a+Wfe;Kq}HnyttZ2&o4Z;jDH{Py;!z za7L1-W;A$)5YJ+ylx3M-aokyDjYDLml_-;xk}9ERdS=8lL;?vW@`D6Ga{LKXzGW6f zBs}v-R>YA^V4y@4 zHwMdj!IfblLj8^4FthTYBEd+G^qE3ng?Pq24oORQqDU)iG){z*!IDym8aEE2goixQ z;wcmi=!QNmwbV5CuuO_{uw~I~G#Y_rkNsk|w~OTn_CYLV{o>?><j&fi{BP}7pY)9-Lmmh#3?oXL zOamOX=|nd(zh3y&LSpv&QQ-aU`1q-{#*3>^YG=PI?-pf7(EUP`%BDzOsD%d&xlbz% zdv@`)GLx0aj9TQ7g5b1c$LMTSA`4T5lF)wLg|uWy!iyvZv-EK|Q}ltj&@q-$``(L% zz=IGzb7VS%kP3_Ox%2CdUPtt|nb&=_?l3XSd8F-kJ3RZ~>~@dgo@U2=v`6wO<5D?U z5~MUEx|5hqr3v<#6wH$$BuX4Cl(i(7W|4VKTA+>0lMbTDB*7#tBqU`mo1mU^eFQO$ z!38c=wUH;xlHJFrV3mGPd7yX@l3btUc?t0>Pt=kloK8}N8Z#-|{qXYn(~p1rF-#Ff zV%S<$r3FT2P8CEH% zSm8l*OGqxk!X;DWz7zr-IW9XE%do6PNi?MKFn6s(N1~#P1kZ6RosKvqJ@hDC^PbI# zQ`SL|{hpAZC6&TWgULHlr0yX=*&r09kti>#pfHahr4%Az3FrnQBtQio#O}=0B*GIG z3BVJD(vp}nC?#nD0u<0Qm>D2iNWkGl2Aaqqio}Fnke!j7onoLOd7(&937F>sLZBpf z_FHC2X_+mfQzUaJhw{7!mBX#cfTkMd(IaB^E(ixAfNk+sGlq_Z%v)U!09qKQpY zl_(M&elRymmUKr6Y9(&zCFoDoO~c4}W>PRi;TDks&0?>}bc)OXe?Wl0C1y|Yj1Lhc ze3j7jPZ>K$A$Xcm9O%I$4}RrPW%r)l$#S9;@LExjKPPqfyfr>FaIjBy;i?_I%g>>C%e#$yxnje^T)}1(B#f zYY|&abx0)z+gWNbRc7T4)HYhrX%v(Smn;}J${v++IpPTf#kl3Y@UY;@j}lFd?VOsSNih5GMF! za%q^U`_=Ya#G<;;@ahT6F16;MKYsrz!i>XbmP*T3u$0PCx1b6^z%ud@lSst^8BW6` z6H1ogj3n{f-LD{XZpZetaeDW1o!3n~juc_8c{r;8X&CoT8g36qr1~wHF&36C z{YAVK&t*mt$Z;?tH1|LqnPV5*d+#!12KksYVkB(L7|o6y1n@G@jFglYx)&~7q1#|y zV`fwxGt3A%d6wDKm`rAwxAYguH!iZ_v)JU@N3o<*VhYWXfvFp(Vf)&>M%Pg`q9Nc1TjMdm;fa> zBM^~^jDw=sm+s!Qjnh>9UK!Xjvofz|> zBN^|>opYp;($wrkKo$&^@=S3#;gA38 zZ~pP${G0Fp;olkGp1%Ea%`f-2>2_Pc_^L$nJ9qn79?r7W`XCQar*r+1ELq=0GCiH= zm+hte^kQe*FJ)c6eDKW=K|ii}z5KyuZ`M545FfiKQFzirEmc?=mNSJY4%rXS)Iy}1~x+;)BTxf?`r_K3|9rLP}BI zjwlq#Nk*Ol#gT|`VRct`ltNlUt8Q8zx3o%J%zIEHT`(aehXAw$*X3M7Yev|uU*Fzh z+MFDNWgk`_1;|wyEi+JCNR{jy6Bvk0o6MfdgyE&27Ubb7)Wm~QcdCqWO+4_tVuX$x z0hFE|JODWZ!!DoQZfW-RcHF$*FGmUoOMCok z-nz~4X1M#I?@sM$+bQGvesH3Q`8Q_7gpy zM;}3Ga@NB2{CNKA-Q%}EV;`5BonWUERLe*OIJzxpSCaXQJ%_b-?I z8t?M$w}d_+|&=dTWDD~ z(kfcY(d}lo+x^Gh2I}tRa?kzh<7R`r97mFmJ`VAN*tL3bMnCWhyX7>(m{ zw}?be(#GuWoSm@_x43sc$)Zt&D7qd=N}O&K_WCmWSY?#fG{o$s?2cHONVTC#qSbB9 zkC#c9G*VA<2#N8^wVNodD&<_Gh%YEHI7ZIbkSx@dsnyn}`+kk?TtPNiE9E75=pmvQoDuHR zmD965npP{-rr@~ixWW>t-a|+v4o}K48L<{L0VjH`tXqbfG^Yi;^237TQbrq;KWKG#3UrUQVhZZ@`NN81SnU8hpdn!VbGr($c!{1 zPg*l3VdXHSgMvbnIc)+Z9GDi_!vnE%+$j&vga^PJJKTw#i5&sIlY4^0!g?p4>csey zo`@l>vT8qiQ@T$ycS2^|oTk)wCrX|-sl^V%)<zZLRVBE~Vhn_nq^B^`V|) z99`9-*H?bk_MHFlZ_hvf+54aVrId4g?$Lg)B6g!Ue0+X-FMO)BqFk9N*1z=qwO=m^ zU%uRAefL?`ty^ENU*YqA`+oiVb^Gx8!+rMs?GMMx$6s8Z?*HAt@`GNxFDL!xFP?t* zx4-=y1O}^yqDI9$&JX22qIbyj8AKYgl#Jlh3D+L(tLmJ(Y-%txs!c&s8 zir)vpwP|_y0@HE79>A%n@mPx3oT4?%8o9BuGV#e9srl^jaBkvsk2o@dv4V_b%{f9+ z0$N$z#w2Bw<~CIBt?=&o+T;0rp5rEk%kpsBuW@eo-RD3Z*WPUt-cD;-`SIX2k7=GS zLACbJ{fkoug;up0A&_7y!fTAE)o+~^)+#oWfLeo=df8iJ89lHO?ipf`ETG%qws5^; zc-BSS(g*3uR^rPWlI^teJ|G*2g)JsP3cxhgCkKVGG?^=L<#55>EfJOaZqg6z&moZ~4mBb_0LJ zlLS}R2-$Lep0QM)TxR4FQY!Xr!}@8}1r{pB;F%8ifu=cwY7UcS%;TJtykgoFxdL0z z-esxU(=rYiQHauX&rWhGIYv`S@B2|U;9yV3`dqG84k)IHPCp8aWK9)`oA4O|F#SnV zAQ?djLpZ1eX40BSz&Q3m0a2!d6bVoVF$WWIa#CiZB@(0w0+KQ!ndrt|AQL7O0q-bE zm1tJvJ>xN>6CGqbaYI_pME+5|1l7zPZea&GY=Vf-7%Pwo$I!> z?zZFUYkEE%!QCl_3&SL)u#17baN)QIp-rF&S7pymo66aP3>hRTOyNwyHZofJD{S#x zU@lIi4^ma~PuQ`sTgFOi(eD|v+#EsK!0MDi&Uv{KB~P>A!-wsT5t4AvBa9q+u7vsg z_51akEo%S%$J>X`w>ja5z20xP%heYhOVF~l^ExlT-K13to5Oq_udf`!MT({nlTGTj zzm9$0C#48m-}gB~8XwUSrVN`+>iYOtz~`qg9?oBF-~QyhKH_a382nh4ZK+u1rH{G2 z{pQE(Z-4Xh{Vz?#F6-sTS1Bhs(#hzw)W^0xY|B&8hljFm-~aB%{k~!RP`-Zu@E3pH zh52Lu`~UT~uit<7&AYFE{>`7Ume-5kxi0(k$&!{_nS_*6igTk@g6bOg?z$0sYMHHh&i2HW)E(lU`@s?A zp_1#gV-eMy=GlE@s_jhfV{~`RWJ(u~Yu`bRnZ1YPbWxjm=QT4uiQliBnKQUs%Nf)l zQW@liWca=J;HVf^R=1rH*6VsedMtN+xaDa-qIddy@#*~P>Q2)H3nM}cf zJffC>h8ZMF1_h(3dVrhmUDAEFpsw@EZaChOi&m$)#Iaklzy7!n#k>{Om|0JS&krws z4v2()34SfW`_0jg-y0YD-C<6vB7#Rhl z$vk#v2_GKekzT_l@<0k7Hq$jtkpO5$>U#wDm=34J3?go%E@}*Lb}cL0Th3X)$Sy(# ziW=OS-!A4?_{;&spog6-W)OoS!VkpJfyIWn5lHlWQdtOXdVJoeS@e0+>Am~W`wes-B+N8BSepp3 zCu^3~MOaqx1NB@hXB-+%RH%sb5;C1ih+AAyPl;smlxHfI*uo-+n3Vz<5p8#h)W+ag z7Ky;0(8^{&%qDRpB@(5!l?qtuKolE{P!D^1OO~aizkU48FFsDP89H;QAeg4>^=+@j zNO1?R1cD{o0yf_7 zbcB_)u=>hOV2*qcS`)%aP(nvz+b_CLvPjwIJbI7$c29H6Y^7C6^MN2<>q@%+a7^jM zd>=WkIhiMpQ+0Agyi6}tGtIzDVoWCzi5STh@F~$#!pL-IK7xHX8)oQgW9dmu3@uca zq+qNS#Ae_Cis+)E6G@br#9>R#S{6CNlB%#dd6RTc6uRA}h0LQIgmfD2Y17Nm!{^}{ zb_``o2#wD>N+jo?xCOh3n}7@%k8-C_uqfKefJNa|KYdt-#q=(WF|{UlXZnpCLaZvjF?JnG)06s z#X-K)NXnq1Rk>9xQ_7N=wX$hhzc?k8hiwfeAqK@PGjnZH1dR)V6<{V(D1n3`2`f)U zPUZ=|P_`5TAnD1fM%aa`Pz;Nb^MEflcAse(qnE?%atrHrpYhT&DJO9)OAv7lNPT|y zb(QEYq4{rchb{Em`u*N}+uaxgpZcg9IQr z&Q-9KB59VgMBy^64=OYdXK~`y&0xEhyxWqcM4~6i zq!VT2JbcXIlaq3&-gj|>lyZ0BRs$hwshP~Pn?XI<=P^CNAdpXooIJXDOygV{!J@GA zk+nu42s0UT!$6cI8(hxBZcgwcDl;`SNe`5Q(il!{(f#l`DVD^JAfkbEI5~CPkEz1@ zoV@1fkraxQxa6wGhyBg3pYxYj8%#nZ(j+W)|c)RZhWx%Gd+wxa`{dE53Tx`w#dmag-)SB?o zZB(wjMobG6_Y8rgcxFU+F-vhtGGfuuQ&x_Vx==;$qd>e?vKzEv9v~2vU`u3(u#<~O z9jaz@3bW}Xbz1i!C5e?L77~=q3?>7!QWA@tEq91WP;g~37+VS$?g7f6Y8FYYp%E0{pEJN((Tg^x8HvM`ImqA z-7j8#`-?aEZy*1f38WMf-1i^~N6dj~2;)hX#M${IS{HX_W%4PYvbI7-%uJNasaYCj z$a$;61*#3>LVTjCD#5yPEF>v~xU>{2)>4(T2aK~jS_DyJnhFP@aSL)JD+_`WS!DD; z$!QTI=5Xk7_oL6(?t8}D&CHVmvPicPJGL#?ckh??KmFq$e*e3VY|-6<%(3ev8036@ zP&lgp^w0m9+`hYhe67rHA8*%vca~+_2qB85r*Iq5-#vYm$K@a+;5ZJeAkaydsbmQ7 zYS-6x!q5KppO>eH96tA#^7P)1?$^Fg>$m$CUw%`U6;v$7x-2|n`t|9{zj*oW_Zhyv z`(_+hGm~2N;h`+=l(;;9dH(iirN;f!?tYi^gRIJ4-<9L(XPe~n55NEI51((NK(Wdg z5yPpZ!muH%AW@iSMi@h69w27Un1ukcf%eFD zWD%rfCJsm2n80bohJAv-xI{VOnqe;>%`~KdEFf_=fH4eaPM$+Zro(J{w@SC)$5k$K z{^BzeN-Y~TUYE89bs~VEqCkR11_?k)DiS?aDZD7(x)=9{QxTTy?d~GPMTFK(Z?`}o zkz9(D6LdYZs${5 z9@}mA1C&X7=<}2O{I9=y_p`sG{3GqI4m0vXcF4Hh+#`dd-@EIKG$slsi!el*M?*O0 z$T>w?s#7?K08NW-=^RWg($Wi46dD?uk2?Yqk%m{=NGbac^!IXQ_2|-A} zW)Aq6c72U~kLzWAy6(S!y?poK_4mK}^{>V+fBECz|6=_6|8)P&=czpI07eQ$bWrQ= z93V;M>SUBQ9F61ErS`HgoU)yI&b(f-2|cS-VSk;=+QOMS`76=87_&_9$%t!e1qMYR zm&`kPLja2c7qY@Maw?xJkTM!!&$6YIn9v;FJ*Dv8Lw2~QoC9}YhCbr*NthTJNi!4$ zOflQ)qf>3`lKk%Z^zE0I+ozA0%xPwG(Zvg2Y`SY(735!hu?|{R+&}%{?e){8Y7^!~ z>&?^0y=~ig>r~#>ZKX}q_FA`SG9#r`gW! z{Pc8wxyTl`{`$pFAJ!k~w%f}OzhATnsptOH`>#J-K3FaD<+yzKuzmH%cR&Bx^0W8# zE74_P@7M2tD-WCRdAnR%JC~=kE&A^L^3C7W-~5NKzZ+PV`Si^{+2lIke|$c@k6-M+ z`+=@ZYL*7+2%qAlO59z9$NXF)QDg+wR)r-@d0`A^+L{BlyI1px)#z@FIL=m=AfXG?6pY^cofmF$jk?# z-bH6uqO9D#L_ZRMm@?b#dhymCjgiCmpz`n_{f9U8AhKinPPuCH8P{p^zC2)L%BR;` z`||A9YYVAwpC8^o+HtQ7eYjqQRU5sVjHR!#?ekDET9)p2o3g%N*XzN#*`nM1R>C=u zZT0aP^%+HS4wfDCB>l6Y5G!3T{CKut2_o@uCOia=Oiyqe$p}jmq_63-qitN)=$^L` z&S{YplXQt|5AE(p28(lGx9d}>6X{ZQBQGuYo?}N_b(MLuXt|`hN8u^UMq@0RWnH#+ zkNf35T~m1ap;~lZqI%<$y7v3MfG!8n7tg5y|j z>Kj^%en*wWw48f$Datx-8P-Rh9fPxPz2Ee3WP!!=|n*p>6r{o0BfcJ0-AwD6pBRNfy`_aBMl*2;wro( z?(FK+$SgQ`Ts#rE`=IFE_c~tp*ysKAe)-}0dbxi3KL7Y(e7xU2cRmINYQS|G0~jO^ z+k?&CGYbWTDi^XOAr+(%aada$X7)U|YvY^AvTiXax2=%FeAXhyovGcAT$d?@xkN%0 zscXs%R+5!-XFaD~Q_o4kM><9l z2MGt|e)D3+zveG;>9jIp@}g+ov*jsI&W3W>G}NW54U4~eK@@j5GX4WDMVhjlfJy( zk0SMQ+y@JYA2_;riMCq2QAta;Ip*s}rxwA_bEVYEOb8^?_%Q-S%T- zU#Jqo63FsUvn1avJlAa*-B{J%Zs}AsrcF~VIk({H&Kv>djB&qpi;Zhk?>DPe`fgTD zgIkfj?=FqPdz4i3R)v$9WuH~sWaQ4%$67Xve!I2zU#!Qj#f*S=PfyolFdgl_c`Qan2 zr_{IlmgC{nOR2kwy>fkUy9X;|DZJpg1#d`;tJ5=$dnXlVPHN(}@Jy{iJ!Z50O|($n zJsZy#C#9V8a--p%JmV0)b!(uP;`iI=xZOVdIFA|3qO7A&E+yFeTdD?%wQT(`^Waiq zpR_E6S)6_E{phl-xBJbmw{eZ=W`M9@*!XzSBu5!%ySvc8)QT-4XvmX35BdJJ^iYF+~Y_rD`iXTDRA#geJ-o0@X!VRF;Td_pFRw0 z_e*zGa+yaEVNV4}ETRS|#x9GEv8wf~s)2|cMdfn9FgM9Kk}G+MG{BUU$)lVg#U>`d@7>5M+}(HIQDU|u|FL@et7xVKYsuA`yc4j_xlgG z{_h0^#KRf@~e?2um{@s5%SLWw0 zzx1weyQaQVx8vn=c+I@M-HxRes>j39LI6y^dCbw-o*$nsKmOq$ z4&?RvqL~O}39=Z6>t=f5GoGe@^rZ$4{@F}^z=|I@_N48E$N88 z%^xrH`2Mt=j&WPwo$B>;`}83)u9wgH?yLI;`oph&_4UvG#wpqvY|ou<>tjozAHO@S z^!DXDD)((|?fgjcFWTjI?Ogc3IRBT2+dux|htFo?P?qR11k%A*F(F}Y1V_qJ(t~v( zC1Oy}<0CWcBj#Jn=BmPdx>>|qbY{w&%MzSzEpH!p1jc;^f!qcUp)wq$7G=+#Va6tt z+{si5Gl9wxeX)kq;vQ5~W@M$^OxoJ4r&KJ&J48~pGtIp$ZRc!Bx$27ByByjz@8|3NK%+b zORM2mutdxpo`u*wOQKr_%=g0=(wexAzHh77=yA`_6Iiv(45B{!sXiV1-5hPxA+2&d zd^%VP=AtbkGlc|IlbpN+6Bmi~jPXi)6k!D?(S!lSB{Y`XK1XTmS)%u%1(K0M!GTrR zP4!1w7osTr$}vfoxF2TFR*p`nn1&UEr9!T!?UZhZSy{xpRCm!*2uOfkHEkGliEYKl z@6y}sK88%|bMBrhn9&OJ2EP;Oz@*6?2@(Wom}@O`bzW1tPom|K_9I0rOE_j`E$MfM za-lM{QBQ{M2bBS%@_(%4Oi|XeOX{x5%3WZrGCKNSSc+-?HDL^j=Py? z$vF0GyouCPDNn>}C=Zeb;*^ClkU#`5fd(G{BWvbhItZGqL>YOfXcUvk5|VVMJP<-z zFn?gyz|1H_2fUIb$L``Vch`)bgDpl34^uimb!+qTHeTlS!>?X$KmGCdufPBG>mT3z zVsahfA%HtTsstLMl&ob@0F=rG_~8~=Yv%Ca!q91>mI@8R@^I>Jug%?|^7x+cHe>WC z1-16P3zx~{AhXJ~9-pw)jNth~zQ9K=s>6UpBd#m*@VlTQCyR`^|F;fFwD4(;(0uVtMtzxvhB{^rl6s;mp4l&AIUzxw$YJmgh) ztEWOX#vZUf?)Z?mZ@*Y=-k-kwvmZYELH_c6{h{6FejM}q{bzpsaEzNQkDX#^LLSSi zi7E^G>+6TAId@r4%l+8i*Y@>OeES9eaQ1xNXnymzkLM5Hed>EzpN>7KI=Kf+Ah@ZJ zjN6?nBV~x7yEZXvZ#3U~DYXJ2R_vrSEVruD$L>a4kn+JJsmDPC~%7Sgx+o!NvPqoeQLmhHZriC_22blC&^pxo&k5A%GMNdUlYkgkM z$6ZFTvjEc6wZ?JO6QwAgaw%gb4UAIhfEI$2z3EM}EM>n2KcQsEow2$#q9#lT*wxB% z@?um&_+iFXW=EcLT+}Ej^H{SGQyupnoO$=%;o}3^Ic&HXvClg`yN+^x8&@o+?ER$b z?9o;NC{ z?PS)u3niI_(?s4f4R76B^1>v>jI6CJZrkFY?l?OW`7{)m(IDcH`I=khRs^=KRrxlZ(;E4Wm}YHb zV#DiaRms?G-AE?Q(=m*EFJ2r@y&sva0VbX%K8;o^P3H)jMVb;4Bcx*N0q&CmXPY-R z3uNZvNG9*xYQOrNJR_+x-Q3}_mPq(qN{SYy4T4O{bU}hTk}?QkhzKOx3})eiNN46u zV1hEBl$iudPa?`S;|hReO*m2#jdCZBv=W{Xo~W=R(rlO=9{W8ncfarVZr2}PKYefC z{b-+l`1|iJ^L5nyJ|^6IQllhJ>hLUX4OPVzVEl<0XH~-T{_Few6_Z5E-Y2VQdTP}< z=IblD5!5G*m)~zsm5ao6IEOuM>gjeRT_oZ6fp-$&VowlvTcj#*k6>CQrB9hmhw?k; zTjkAgFkVxVP(TtX89SAl@hU8Vnz%x?%r_^bx3F6drG85(IgjY+x+2TdCV%@c{>4xJ zo1Z=Xv!A~I`TLju_y6hR|L`&1{nfbt<}d&GPru^NAO843xY|BM7Algl-^SR^@8|wn zzy6CDzq8MP+$+!R`K!x*6p1#ftl7LJ(d~LGO9_{G-QjFBQ&y0=?X|44$eGu2(msxu znbZ3bwcfaX*}nSnn^<4|@P|RRJS@kD&u*_o#pPzbGynYl*0*o&58rNOskdz*@ayLb zozML1A4}cVr>}$O<@NVpy#F@WM`fMq0-=7H`z^NU*X#8+Km2*Tt$+Dm757-_;d#~h zH-G&v`}hwp$E|`YbUGD=8%HMQ&Q&77$8bhUw;`*r5KMDB6XTt|em--J#%xY8%fmDJ z3ui?R_GP@dz!RJ0Te{A9Rgz8qCJTcgoaH%&V~1T&mzaw|6Kc_n?wE_r$5 zO8W2(X=W%nRr2!w&%gmYpw17ch=U!(Y1+gtB&R4U@|-c#Q}`#z38GN#Ou&^v3Uc}P+gr_<+pGEz0L(GvZZIK?foglLei|2D*-%5GTr#ZfVYs=a9%W^*1 zbTgl?(auYhDw6HtsgK(fnFt}69@(_6G>q6B^B5=(u-C&Mmb!aXq2%KI@WK8tWnI+N zV_GX|$w&8P)uLlRScJ)NNiJnv^Wlq1lR{%2DdL;wA|PuG7J%C1^Ni64<^A%%Yz4ej8qGdZ}s0tmW9_9sDNc;Q8b+5T8o=#KHv;b72`tIBtVTYn=o# zbI%M@Vvf12vOP3rQ6;7V4#+7v$!g{SC`ZjW00*krbWSjFa=5cpq!C?-7Pu!R%}knz z05QcIxMZ59TJ(fO-qUvh9 z=j>zHsL2+wwa4I5N@GtdqRkS3@ni^Cua^%tePOwe$q9Fm6Xy*~oZ=Ck@*#r-3@SoF zodeMi3XRmtK07-h_Y5vs4qG1Td`)dM7|U4#A(iJIt-=OrWC?Wl2oT*dmig?q$9JDLGnfX(03ZkgAPF)^iC3gRNk2_@GQp5| zr3eKjkpUS9B0#|r1kjk7o}TVLr;piw@6WBZswy*Iqj{bTRiQhiEO-jYhAX;P^VX7w zB*u@gEW}=H|oQu+4~4)c{De1sEb)U&FjN zLOPm))z%I-NaOPEZYVTd?8CYp#+Tpx8$Dd0R>qVNrGWyy{`R}aPj|<6>HMRMKpC@q zcQ<3oXvxg>msi8Z=J3s*zy0d_WBMrJMu*J5c>A+?H~WyO}$y3Kf3yP zl#f59%g5>IXVluoXP^D9U%&eP=P%!X*X9OIj|!wJ5}g>GWJGmf^_B{S0f_amAPViR zA_FIDhcFg1X!jooi&^8%kcI-PwRuTqI;2dtwnWB+ZUB)jdP0JX1LQjQyk+-J&Vy%V z)fPAfglRKl7@MsWz>OT+m~A!OjM3b5NleA#qy$PHE+t!GUaNzFj0{H^M^9v0y;2Qx z$@_uDG@osgKptp&wZW+35RSx!yqC?C(*#@Eo{~hweuQX-z+U2NvQ_ zyOk&0UZfEjj%jC%8iZCg=P|D5fYtAVSTLV309r#r;%>e=p?CutEZ@6d1|h*J!_ajW zGzj#w9z=e4I`;16shME59G;iu{RNbp5BoQ-wjaJbrhz&wV6~GCmh5CMF_i3zz;2C? z4JMAhx>Ic(oymwdgxo~?;m$0$_h!gahITlBSzW`0{HQc0Z(tsr!z@~B9y#D-vE%(T zO{A5e7HR!yP)x{Dc=ORObX^XpzGSd1%yFx?{ zhWQjRb~o@CfI5%l&DR-m>PZ;9tu9GXBKZ=1b3g^06&dd-v(OXh&P|5m9Ptxi`JJ9j%!~NTbcdzG{AKJ@1e>ioM&8c^G zZ<jgC~FvmJ_%kCq+sO#z+)7 zMZ%JkNh&-E)m35V+Wnz+#t9@1!8s*nDwz=?V@iRZm;wYbfD%DxfRNA-#DIVXJOLqC zQ_bQYT-<_K0ucJiv*X&mLs+uYyr|7>=)IWnbawg4&pvzh@BiSVzy6c6bN|iX|KI(; z|Lb@6hv9f1wd!zDp8Vk-+1c5j{=fd&;dEM*h(o<|N`$uA?aKw~U9)w8G9WO@kU~+C zGlQ+eX3x@2hqbTjrA$cxb5L{*b4uvlkOq-9I8hRN{L!bEpFFMaKa{*(?+y^B;mMh; z`0(P*{fBq!d>m2^P(yBZj6my-(E%&Tu$)QN~$C<4qZNEd}xSK};ThQwl8DMAUEVI%>JXnh6|@5qn@pc`VE=gMvF8abd> zW6CbTLEs%*t80KO%tz%UX#HTd+C(@|+HQF>meO^<9d}#a5L|%oYafahri(nDQ=N9> zF6jo0|AJUyOx6KVN*QEMU>k1iCrQLeU~A^hHrf^IkUUwJ0CJ-klb)m`(MF3#N$83g z1_5mi6mW1O)Ck0G2Z1r#iPa$x>jzduVDwJwsThtM$a|SKGG6esiTsG|YNDq@dj5nj z9-m!(e7S#ewn+sNlFdlHtCu949CTSb%sp6`#2g^pT!EPbBUC&Mv_vH0+`Au>%>L9 zC&U$z13HAec=Qevsv3Dv4;eXn=OI+d!@UP@-I^0%uzColOm=a(zj%(*`A{;`uwgQY zKqT~ruzGg@1vfwdNba2hJWwGJjXAkDLdH-e#&`fkAah5sC2%0`02HQZi^9>W^;Nv8 zE)QMveAf>Lzj^!N?RO7vU-z$H>-!J=<|K#k<3l6JjXLs{34|ya4!dzjh~D-SBd5a3 z1M*+pf6fH7p*(IZBKH;1a+X>#0-z*8_XZ{VCJjiPz^FN9tgHKS!T`#A zwki3XB%O02fkuKQ?^h_y#GokP(-u1M7}TZnz)nF3Fd!IKg%DthC>+Xy!4{<22wbfJ ztgW|N8>}-{9Z$g1{*y<)^Mgpz|X8?RMHfyn45&B4HUM z=V==AdeW{chh_D+w(3ceE*GoOIPt?(@>44comN zuJr`bT3^}F@`v3EqXK=2J`Om=y_Jumj*!{Q8#4BElD^lIi5kc)*gW=t3~ z4yLZja)g>;SPE{y-n+7MWaKVhoDn&>fdesGasY4&7=|(xKNx_!)~2f1DOjB_2)X-s zvF|7ol1#+A5m48PY0T4(IiHWTstlHx$BBVL00&P*sUHkSjG&ky5ZKXOwgkOFGf)o% zstSS$#G+S89NnR#5&P;eL|ZX{inyx-p*cbTq1RO+$7~qgo0(}4qk{Dgow{(WHJW;4 z4~OGJ@I;B7QIuthWS&wf*r%-9pGi%i0h)YDWz60V|NF|NYiHUuHmJOASu$- zBer^fP(x8{B0>!9VU?joZ8%C6LTJ4YY2q>Qp#~0;fXgttD)n?&br|L9a`@u2Co-M) z_rIofPWx+H)|-clnrjPRPTMi%9-4%zQAbBX(AL9D$tm0mV+WSD29XDF)73V3eBW^J zaOknNiec#3x@Tp#YQRX?yt{9Dk5*4W4SneDLLN;qER;$g@if|63jEo2xNN5teLI7AoGyq1<5H)}(95GQs zFo3WK$54pDBLae;2PLuu7657{>K1iStI-EN-S!@R_4PO(Z`Qkaw{Pz3{hfYzKi^b0 zBXg1cWF*F9)`v&uadR_?<{ksv*$#JQrVO0AU3p6ojH2o1g=c1RC<} zAw(T8VGwY*MQ}oYz!-s7YCG`RfkGi{wIzD97TZ44DW8ut?SJp5mw)i-lfU-4(3`LS z+yCu9_&>fncK`JEeg<@^hk9yvfXjA#fA}|d-!Hv>xILZLG1iB9W}#l^>1=xP^hrCc z^Wk37P}@Ua8Hjc5+so_ycv+YGldj!_QC#bz=bt3Dhli6f$KnYiSg0eZdyd`t_R;50 z%Gnuqi`H{KTW{YBQa(S!X)7fs+#T=Vgeyo|j;Hp}!8$@-dsnyZqaQ-rp)K2IA6@_S zc^)x~AAkGi{jYyLpALDvT9>=s^<(q9G!DaVg5D^UH+D9Cn$j7cKHPk`pPOe4rk9VO zJl~(~hDSUOBFLj&+#O%8wUIh7Ix`80BQOE<4QEnJcw#Wz76+GzG2^=EvAPns@Dfsc z-|YF>`IHDhJXo!W;E*PQ4pOK{Yu$rFk`y8BZN62|=YoiGe5=v@n1c=)S z!i3$_fNYvZFrPIb+PD{}6nz0IjR8?X2>=Zs1jii~fZZ6qJJ#BbB=5FKhcrx%c_hF* z@mR)9PL#L}h@EyO*|aMn*G>$*r)=mLsff9UBd3rMF&g$p z#(m|8AW~vd05T*nBtzybhFh`^t_VzYnw)Fv41vAKe(DMKYo1vbU*I8pH9cB+ITCtx^oz?fpJG=@ZK4mB5JK%sMhGZ zT7#(!y;?OJcNc`byUJ31H6ahvb=+@Q*CLcgF1a8K^KoViCP}+pAlckg85dolAv5A> zZUNKa+1vd?%e8Gb*#l1x3r+c`n$#YBdiL}=m))*CyxxQbji;XG53e<+^>j}mEp4{G zmMt_N`m)OA40=ZnHtcysBCKn#iLgZ^LssBuYX^4DsIxmYv(WC^DNVDl&aQRstr6^E z{UC(Z5dqiOiXB4HR3QfS$k4ihBZ75i3Q#X^eb6dP`06IhvCZj~PagogO z^x3AImtkAdG$KzRhCzraw1#)k05|jsG+^`y1d4D(9uZcg0n9MSd4pic+1&yRVb8Wg zfOEK`S~p`PZwtq&y|JB^dXl=F?jGv>0Y7{=+`VrPRhzXweor8nc>mZ1~XH}rFCDx-Tp!@m^Z@74z~|Y zu?QwUU*mA~{E1*%mP4qUc##yk@^}V}pq^8?d~#7TreRCSm2p%D4hNBhsY`^Tsbd8P!j6F|n4BX?YIV(&6g#*h)1XF}j4Wx?)yRT7sr8Ft zoC!?3q|#13I3yRZU}huB5EM{L-T~4eF>PgEVh4-^PtkLhJmi!tqYyZ$0wM~vwMBDC z48ej+AcQBd2rL55t{$CFBAE!;R+c(15^LAb4IJU*GA;Id~&E~Y6CeB)jg6-jf2XSbT zM`nhm(G52PnMG4a0$Y<0NQmAN07|rKK_g?g+M^M!i$@|(W*Y7)nb*1c6w5uJuf_na zW9eAJYH(mfC(3}<(V!+F?u*BQSadxJA)+XIIB93lW&s>&lluM~H~VSavLqt}00UNt zOkTk$yoM_hK?uQujvfh+gP2f2PZ)%O1WG{=l|g_F+6e#x2+XY)#G$u}O1*=x*nF{- zj)%J3J>0!Net36(^Sa-j*4nYA-MY-A7UTo?;Fwcp@oD5iHs?FoP?ju-9M+!lKil96(Xh=AC5>v@*BWfrfmQEs50ptoATX1&=#x)> zfV1A+pN26_=bPq6)OA)ZiIu>64@=uIr>)sx94~vV>vB76$4o3Kl5P8Zym@zXYHRC` zGHiCc{q>`>tH&45uBXk2v84U8=}Eyn)b}4={PCZ6)BX9=-s{@#$Ni1dt*zIx;)3 zgbd>Vo&yr`z`cw`&2JXyvn}p~lsVjCJS$u)8QiR4f{f%{1DTO;R#*KoEl` zl%__k1eOXb83y%Q-HC++k#HhGw`M4mpim}BC8ae(RYB?&J6#fqN=Zjhi`T_v(?+)zUT~9FzcJ zKNw1KgCQ}P7eh#ph|`9oMH0Xi39&nf1TrRfa)CT0+-|nlXL0e#etNRIy!`U%{sN-= zFt}A5#xQqdVjecRD>I9FO2c40FlMb$%ZMQ|4N9EP&Kjp&iXh4~l=HJGxg_S4bB-7{ zdS4GqFAVOHlL7AX0J>C3f+&VGFy_rjZuiY{mc*htsSRGn<3ZDa&#up({`4b{h_`Pr zCF}j(N1gA((9=XhY1+CW3dyv$&BS9u1;WC}J&X+!01U)Hje;Oy2ZAMp)Tmn*1q+G3 zcmTN@li}#Nph@`ZC>cOo3wKBu2BtwyXx)~TC?Q8{5zNth#mbn&q5=o75t2+6t7-yp z4R?~zMrjM-n?Wv~P1BX#DBNm{OH+F|Kp$1ufF@!pMQ5hpVSZ?AT-qNSOrrlu+76D#mS!-vbOr5oUrx!a94&)Mh)|EoX9bdn;)n13vh$1<9K;|cQZe{ zPs0^ugOP{faXs99cyZ&2hk`?vtB)Q>djK}cH4WSRWIygxV0`%bufO}%w-kUQ4&!5= zPkK0TY-_JrMoLrK?E<#%U%zNtIm{Pf91f?$c9%pFoqt4U*Y&%X_xEr4Y(MSF_~_}d z+RHcJXlt?tuF>4H2d6yxeY*PG?LMJ{$k`dUqu(E6CD4FsO6p~p!g>nWZ^m~IZGZvE zs#89jAQXFzvcZNCW<(j-n(~lS9yp`pz_n}0P?9lA8A=fzMAS`O7egRn5KJC{0x%7_ znpkh$Ik_0GN&_HE>9( zIj7we7Z(@%CvEfO`t1DaWw2xKYirn;z=>9C0s#=1LY*x-W~PK;XvKkn358XwlDTk3 zF=^}B**=&AVYu1=Z+kzrx#yD9kTzMhGv(Xcd(N4un}I}~refx`ayJABM?p?hO09h> z@${qJ^WS-nYs14^%;a6#X{`?4It*i4=W;eUC&9k)wWmbtV8poMIJu1ED~W@Jfd?k9 z4?S(!BcQ5h7E!ARjI9ERD!N512L!3Dfhq{p2Ss0<21Cemt)SSkHnqg9f}a*_EtCYi zB8Pc`)gqZK;MsHuWe7#0fE-cXoRHWw<$U?r#?6#6FfkBPN&pxT6pO0^8kz)lHZ%@` z6zD7i5Fi%xV+6Y+b3g4IQv!$_2(u$MSDERlhHk=2YSh=4O6X3CA6C~c!H$Q(3+3%~-pw785&-m`A6;nUBjKm3X8-_8H> zAOHOS{;RKl>vwH1rpw0{!~Wvo?&0tdYIJ=z{QlqhcP>Bu=UrC;N?KT^!x5P+= zoN5>advF2&I z7{=Xj{xo0Z>3m}bhi`uS>Q8@(ushAQp6UeWI-{0;({@wHIA4q>V|7dgZ#dGq*;oH}69G9Cvm+R~8Cs!r5%ZInO_YaCe8HaJp zUK7$V6gizRO{hQ#i6!Q^?Oi!Rh<0~ob1R95ZQf1!(1nus#m!qJDk2RuYIoPfQq^Qg zLW$UUka_87>K2fYlAsx2#~$HeRzclClB*>Na~Q%~Xj{WfKp>B))L=GnXb1yC1lKMD zO@Jvokudc!C3e~{1VLN30~0cEgd;%+8=-SbSQUzx8gAHEN3>zb zK0}$rDWpZ-V~~WJ19l*akTJp0$}Z3`lnf97dkbq36lw5&L=kWY0MrVuhzJ>kkPtB; z!0c(Hl9&O}B4wl%b8C10x%i-p^fx6_cQoldG^>uh~4n+q)fOPmhJp~RLBS*;0MSjZ=n$sC)bnH6s?CI zjXj!?leYuYR7QMs3B$gO69@xvMyL^i>SiA16bS*s4L}eH#V|4efmPxWf&x1c2L%QY zt>J?~MI+PZRsYj>?S zjC^~n;KSi`%sc+_C(nNNH=ZMW|BHY8r?2jP(cb$}9DCGmEqa%xw8uR0fCD;V>$S$s zymp@@r8Jawx;d_uk;oTKgRC}A@aRWBOvl-l72FYnIPI@?5uL*U(Y!B*xi2^`H@p3A z+MGMC1ne^&-yfF4+wt-$mEswO-P!rm=VupJ`$r$`o_}06oG;F{pPuE>XqVgDhj0JI zzdU|84*61KWGPk;`;X7J@^oEKc_?+Q$u*apFB4hnxAp$PYg>jZ`N7}#_qI^7d^rE) zr+D*bxpx46`RA`*{N@+We)7ri=;##n4TGD1s1xIrS9)5Lp$&4N-)>b;oemK1oqmNi38kaT#Jj$R$NJ z&djMYiUDCaU;t-qGe`vQygi^M2hG|DRI~?@pgB&cE0IJXlT*ip=*Z}ek|L#GLI(r` zMyC|k-IS2q+5kEx^006SC!!#3Oc6j1D%c?nB!JNuJ1vD%+38{iEk+@??ZVJ3g%5!VJONsuICr z%i_%{D^nscaJ6PJBv6f{f?}LX5jh)(OFUZaaEx3%Ib>6dwB2a5$sMG=TH}B@XLsdPj%ZK~> zx8J}2?(Ws=4==x6U%b5kaNB}t^~eHQicsVYjT0llF063m5mQGZCuT_&0eUpgjMnL# zM#}v6{`%jQX+uo=eHMhYL7geoWMoE!jNU>5QOPvG8#0c}fa_2gF(AMqtZJ(OK#-k+ z0ne2oqq##^xKcBc(kckqrvl@M3Ah z<(jXy!_%W2zrOwd{n?9O%-`JiSgRfbTC;Jq+EY0@-<|jM?uTD|{Ok{Z{A9n}{Oj-k z`+xrS^e`{oGE4LZg$5bX!wnFquCs*ZvhCV2!*V$FplO-{6kC~lH^3Z|ttTm&&v`%X zbIDXTw$}T*gSY`^0axslMv8KK|E8@_ml=G%{PHJ5&R`7!wJzXncGu^%-ro!I?vV_W zj8{`0G4IQ8wdK(;cvXJ$FaF1Ge(}BgP&Q@z_`J||y}Q%?VSBzWY3!|GVuMZ`F)!9N zT8RB>9qx%-pvUZ3sPN5A)@a&b0%z}IhoTMvzb zsm_Q#l#H!5!?6epOba5KF?qg6iYW@jOa0>)p{scU7cLQwsKj3FDDT4Z=}@Hi8|M0~rIOut5=T zIPBB1*fcmdf&qI^F$V>t0hN+JAdd*m2+8 zA{YXPj8tieuo4(N5aC3?M1Ybh5DGv5;tF6$0xSj@rF)v*$ch%0s`5%OU4QQ-1C zT|eFLKf>|qlkIeMHPE`&Q=Pj2G6EQQG#0bdx`v@qxS5N!tuPimCoKC?gx7fyfz8?3 z>8>v8DjQ*zZq}o&{d$`}|KZi;lgIt= zz{{Sl=$Xp2S+!AxG=i&K|aJYQ0s*;?|%g(Xu%z=34g z1_G( zY`wQSxK$7K=-#?1VOv@2_F{W}RfZiWMji?PAdL_wfD!%Z$k761K!ZR+DHu5r9hkUB zU_b&8M<>T1L?y!Jm?P$h;x&0cG)q=tbv?a)|L)u4H{agB{9eC*wY<4+k)%pekBpey zi|{z*91&`a9zrQiDbtWSNzMe!q{K+34TwD3ZmDW(m=}*4oqw!=1!5lkvdCm6-@75n(ZaM64_rnm}r( z5IO~WLTDZ71hfq}Mn;Dc+EKQ^yWn%*J>u)@*uQW)(z_S)pWWSl+aBg)?bweBQRZ;T zV}w3>`a9$F9@F^6U;W+9)pGjP%Rm14tFLdCj?#n9MqwFp60L{8gu+{3ixway_f^WbLiR@UzUe-ammbW>8^L1M^DFnxx1N9 z_1HUM(#?5XeEI{Z2k%STZQJo?eptTwiRQ14xcv7QcPyU*M0_~atZ_v7Yt z{nKZcSG>IVlf$bIo~R%7?ykLg@y*4x?Vmp`XHV+4-`*XL(B>geq&;Vbx+2Rq0S~mv ztm?N%vtE0Enqtb5aRPmO23&T>w+|1si$lj$7`VFyh;?KhL~59JA!^bq(?G7^fsV%L zY9p}aKmyjRYC=qmn1-BpTqw!lVQETBRl-1|0dbz21+V}F5Tm+*2So_#u({~-%{ZN7 zTX`dSI7>-U3g%LYo3K4p*f3GbV4(o8296P{kWnxpLMT#RdoU!TM5DS42;u8OA*2;i zt(=jr&;Ugc6s#B|3JoOhVy#D+5KX!n5(L?H&w30_7?FGl92puQMoI*Qi-C+7$O04t zjEu#R7?{}!r~(a$0&XOP;NgHk5k>$WnJIw)djJg)4a|Tu12W2n?R*?BpTh9`iZ7mB zjL)~Q-1G{j-8^cTTNq$2=-n-nyC*smUb+nfkGbj*9hHO2qcdDj^ZQc(c#$MvRYme~ zZJPvOeV%bBYf8DDR$FY*UdD+e_1Q`uPIJ4s+I;fqZu{)oU;Gkev`EzLR8#f3a2BFrOT zJ@s&(&HG7Dhxu)N^Yx3@FAl%`M!$Zu-p$%A))k0S78nzZW7$odC-lIaDM=K`i zgIG9Q4~=NnaG>NNLfSBo{9pd<|CCY@7LuAIv1|x)^cjexm&BgZb|4G`0!K2ilm@@p zN;o4%B_$hdNYPtZ!choflXDp{l~RyLaY-YODNjsklaewG&f+*C0;WKaND?7}CyWu? z9W&wvkqyp~H$GkZZYxhI;a6}Q_T5drYs;Zo>(N@P0WBWt61_y$-Tt$WzWj8#{nh7x z=Rdgo@fp8<`Ky2R`l}a*Ms<#5=3@jR@qx2IqH{eRF_xcKDDNwz#C#a<@i zj!Z1$uJ*&(rx#_q3|%;H*LEu7jsVHEY+D%y2Ap5~^4Sj`PiwsVCqMu0yYJt8^G%dZ zim+w-@;ASk@cr3mAIW<5^{;;(iV~Uxr<8a~A!*3Yu4%KmpZootb_va6pv&ASd?>Nq zl`ZqT#p>!N9M&@t5^C##Lu-vj?lOk!6m7HHddb~8V4xbXMGQEA8ej!=g(SXsN*Y-b zIhl3ItV{3F6ideB5fCW@O>AEC2OtDDB7%c(Id2_Olh6@;pQO&LzW`mjY`fDre+*GM=vEr>3#+wTOG$u z(c|f~`grm9=Jw|4$LAkEeRT13?8gVgP2At~VXQ8_dpbKO(oEf9Z{SVOK}!MwR^7`lVb+SX`uKYloVcvHXo z`u>~m53la}+(iRm8ib<&jU3}t7;!rkFim4(#{!yUH)f5nQZi&Cm@#k;>fWQHQ^|AO~Uw>R8U0oa02{XnW>P$~w##jFQ5U9G#}dgA4_xn8q7Ez3$(f z`n?7&-8MGA!`7ODX?j>ym6z4hZu{}aKc@8UG!8%byMHvccYpTx|KXo}Grzy9s@l3a zwTJ{cI6%?J95sXk7_~yx6P00KhVgPcZqE0QpWeQE_5Q^N$1uWak_buTmdx^yb{}7O za94%q&5c4^Tc$_P&Ypd8^V?q^ZthGHxseeAFSqY^&z=mj^%x=6yczRwA=8e4ODa=7 zANKosSv%$Zd15|aUVixM-+qm(7tfyUFFsZ~aX55Zmvz`kPJ4kkefTYJ_rqpfXWNdc z*Ey#VlDl_S1&zC#7v-7{o89{1>9=3~>h|G7$!AM{znv~pT)lYtI&QwY{OKR=m+kF` z-&(+gMB;TpUrt##Z^!MB?r!P=ZXGddZ4K2DQXctoh`i13-rjoyH3xzrkG*$92@Op! zQfkHoBw+x^3}(y>Bm`w}GYSVsBP7Q##X@B>f-e$i9YBweM{xrMCztJRoWeA%>jPDw zA{uT%ija{Fam<|%38`eB`pi>d?_zFdq=bkg66Ow^Oq+*;2$)8Tz#!N%E@mrEn-n!1 zm>`^y!?i*l$K{?`z{SCsT0n#Zc8|>1XYAd}MB^@~djNGcb^swf24~2KU6BIw7D2%< zr4cg=R^%~?L!K}xO@t|X0dNID;O<_51_*QM937kx763$H3>1(EaO@O}5y&ar9Rs5i z4PfB_guozM!Ru`qpGkRgy*vN3DBLc$T7aBe?}40fZ~-(Q1tQ7$cI#k4J`82;^R&MP zqK6L$I@_4mVc^5kGecb*5HNbHaG48{&8~qYj$}qTH{{L0H+TKxC!3GHIGfI%^qW`E z6P7%~mTHUWvO6cz07MK27hsB0CITtedX$6?3IS=1v~dY>ifp8X^ud{B*g-qV2oOWI zQ{U`t?uec8fE*A=!-xTvD0(LnkMQn9Zs>&6ydh(l)d0%e9u_1atRaK-btqX<2en)X z4PdzkN9fuc`0?nyr#wt@*zX_jt~KqZoQO#PH-HK;0~H5HumB1ifdFwtf?y`_poG={ z1xQg-V24OysBU2H)vSk}a=X7d9M{|T@%HOi-@RPF`*uC9m08Flt8Q5K=Qsk5Y@9q( zMhsTxBtE4<6eSfj7Iq78bz0D4xK3mZa*a+Pjdxk#ZCQ>qAAFvd*|IJe4(rjXd(hhPxL9BP=!rMO_VS}o zzkGgt^{f5Qe*DQFemVd4*Z=+h<(F?Oc|ct|rWl5estULR1u;ZRoTT_tC4hT`nC6Lw zGHyS+CfeS7`a8P|cl+@gQLWm!Ez-=3*B8;ij%wQWEj;$@8+`9l!bJ_IOfP zU<8M#(Sq9HUD}T4&!0=0h+uoQ8>USb27=4SkL^%z-@m%NyxKn6^6v8H#aE{{emWe> z2DTqv?5;ntQv*iKA_dCXnA&uB|NZg)?(DNKhCC8dT~}a)MuOWk;kfzCsz0VXxtQ$Y z@g^>Dz1v+ronL%-`~Kzj>Z8le4`1DXd;OQD>mU6!ee?cwdm{;=lLt%YiyUZ%%(bo$ zm4H^mEn=Wzh-?I|_S}#4_O7dp*juR3Zw&8hplHJrZX^ z4bLNY00)4M%Zda&kN|*2lt9j89z0SSfhhrbNrXW;xgjQr zXzoOSh~Vk~Jutw5oWT!6A95a^Ys;uPcPu?>H;pk z-`yNmWFo{~8vz6Q*?#KSF3*RkZU~b&X&*L&F0~!z?v%hK%V}*ALLjwvla>>HP%;8`vR21@9n&So)LOP{P3Xm?cRNx_ksRamg89^%`Fp#+u zGIVn(&R|SBdKx<875+96-mSlk}^6nqX<#S&MDM8s6lopYG`2K z&STk3vYC>2Y%}D|kTP-_Qh~^$1Rz&%a!Tk&6b7$>BdH*rFentkO>9GSPn{h}=QYC7 zB3!`))_bF|ALjKTR*h3l4Wm4H^!&4*<^KBpcW?jTfBr|CC)3ye-9P>pzdE&MPGE%r z2M;IcOu1xMwMcn8OjZp%I%pz>aoS)g_RBAREKF~|`SrW|2S+IkCfFkq3jxvKPri6Q z4i{GY;oYrIYxuL~mYwT_aG2k_T_yScg<>>7dK7DZDRH*L1cY#wpV_y!Sd( zJq^2y%P&6KJbsLM`|=CfB&0blXfG9FhCx;rIBm))2$o%s%7m*YoQnkeAwm7i&9%0PpPvbBFF#(OM&L> zst}NeK_y!Rf$&g;Cb8&(F_>FJ!&Boloja*vSltcd4UncLPL++q*hG z+KOl@nMCg2&8=G@Lh`j!p2!ujHYU=D(Jbeo-z!l>$(%wDr*-vI($eZjA76g_=~d3+ zVz5My@U>PnWhr}TjhGZnmP+gDFRtqpCl7AI!i=HR6qeIcO(L&giHVlutWqJ0v0eJ4uBy7 z0U^TTbTV^2&3#$ge0%(0hZnD2y=>oob@Tex?&cgFSa2GL?N$cP8wMuG5lBK@nmaa2 zB?SX0rjalV8BrtS?iUN|q_xNTp<$#LmZ(NOtUz^H`h`foxD3Btn#+OtL`F z!GsR%4_GpS01%>KIHCrQ)Q-@=$uU;YGp|Q)s!AUGK&84Y6;qaRbMf&Xe*EHp{NtYO zcmMq#t?Tj6|Ih#E=ifdw1};0TYgmV{k~h#Tq(h_}iCUXO1AV{0+@D=#vaw9s4(FeJ z;t%)lzI%OtY8DNd)dd2}w95nR_7_jS{5(%vKRmp8`3-1>!^fA{*ESGwBS zP-;DKpmU58=NDHXr0+l6|K_XLU;Q%tHa|H>EQCcLUd8CwKly|G53Vs5efR3s*Dove z-R9C2AMS7Ze7kvmISfyGKjboncPgHJs<(IR>EZ10Zu9g>DqCDm-Ph@2E7_BA+}$m= zU*EmO!|mJQSxQ%5*!%kO^{dcQ*ZJ~{Kl+_NTtD1hUbph-C(Fxk-`?D74H~Ji?EXwB4(2zTL2~sW3pv7zyS6rV}gikE(KZ(${az~>qJT@o2@9; z)X5+hUwD)hW}OpJDGV_vCrVkY7pt5TY6Lo{6ZD*zI-o9{`n*=*VbYa73K$B8I!rr) z#%7iX86i0sK!lSM2U!Oowr&U*6q2L}NC7cjgKz*;lprS(2y4hCn30gC0E7@@0>Z+c zK`MpdR^Z))f!0i$3W#bi(|{4vn97zWT2sjk4NNmoldK`tqUuHJ(`UQQ<7pf* z4}_SI34tS+Fp#Q?KtjU8Oo)WhJu09CDM1A!0sss*kACd4+3nHhoAuu27dN+W?CW2? z_~vDN|Mqxuw?gl^Knb|mV9qHMus8wX=1dKu9?Bp{9D|IAoUk=URzxogUQ$%t|EEKE|vq_QwNEyY+8s`j|h)pPh6QH7kixCqLxb{?NIR%2& zhEZ?XU^@~BPaNZByWy6GDGlIxizQ0h06O9s;EDmkh;Ebvsz({X7qd)mkrI*x4_p^d z3CJKIQ~(w-FWwU;geNT<7d~i0$^P@85kmWTt7_j?W$~_ct%U{`LLciP9*AymMW8$>sX-^|Q}^ zkhDq~-@bWucZ2Qz^zi;2je{NTGST$t+4)%RhU$t_U8(ZrDs0rg40@ z2VBk`KTj;~r=0e-9&;H5ig$H@;Xin;emarI_;gaWkT5r-rU3YZ`b0v0(VMC2`~6AMOoQyW@MGXN4xW6O^f=;XV=eu@EF&7j{(}Pwi<2d7-ObXGUzgR*8ucmq#X-7b&O_~nIjw=LVM*Q zGl^LWBPI*A1WB<&xe%R$M(rozT~Kgz;ES*$h8iR(2E(3pwjM#ig>-2YVbHfb)||u8 zwE__|gB+XfP_ksxfo$3rVwPwLndV08ZRK5mIIbu4>SZiv7v;$p<8*#D?gW@PWgvnG zWC=6GjXMwv5`~P2hR6X#Xaoqr0pw6UdN_Dn^~VZ93r z@_+H~{$01gwgv)nfnh_43c_xV!g&k_K?Wc`KLb5s*=BK`m?+GV#bE&om}~7uY=}c1 zvP{KuPUq6LSwMuRop7Tp7y=^f3K;bM@2wd>rcX(O>(6d)R74P<~sIU=QGJuuMw zsdorM0`K#>2BdKcTAqFS?E2}G-Tv{gxs-fXJ1}eqoO%G4q44%>bNJzRx1ta5)vfDWX_3vJEp4*wIK7-f}4jU=ahR> z4Ihb`GJ{zJ5eYby6kYQ;stb7J0NQa$sa7=;$T_K}-K1dXmIvWHVacm%nNkUAO_SlK z5Fs+VBQ78qQJZst@SG62we6HWd^#^SM;?d~P;G(+4hT$xAYxDkCL!`vgdhai0|J10 zgdPzCcp7|fEie%wGX!!XhSn`1gkUIu<1kVsmyVc_5W9wK!W@IeR^-WdnGng%Q$cD# z1F!)zN=9ZFkPIjS$s_N{s|PT(5Dc%#lTbJcxPe=6MwlZDxFQ7*hhuO;=nxHa33n0$ z6f}p7hy|kojDU{nkTODtU|@_u03wJic{B9gCE(SQA@*|n{fBwwZo}5m%e+)FkCM0B zGEBK4)VpO>9j0V!H?t(957ooA1FdV%9t7!rUYS7=sndtkgVKH+5!U6)A76d+>>}=8 zF>bnpuC>d6({?MyW$5ix_9JQp4q$31AeJIUtVE;hEIbBBHWUc3Ln@d$*)S4yjskwb zyw%=V3i}L{T6M}~fB+PMF02YpC5;R{3xguCq?Duc$QfgeNHCP73d1ysE+yl*9ZJ%~ zkqQ+vbLhP+>L}bVeAU1C_Vmk_`tn4_m5dU3&xNKjonK5-;Y5&%WXeI^ zv?F^|Bv1+AY2@sLm?eOiC>T7zAcR!J9pK)I#ZOR~?%8-V0j!tFE z)QK~LJA-7U&u(-Rg@=AWpFjW1?p|O0?0Me& z@YOGWUKa;WI{~F+WppYlF(ye&7}$cwgqvwP->3OVJz(t?AetXOwsa?)Fo3|+U&Y32n-aR6ptru)-!R+ z8w7{7=YjW+Mi0o4_G#eIaXW6Jp@c;Wqzr~JgnOupW6pxi*i8xC0MwSmHS%WKjomN_ zcp+Sg3xhjF@DzeX4Wx*!h9lF1wXkuL!%d)|2S{>C9+eWJ7lGL+6IAgv@&*%7>fr-r z6JG!)M}#oZIUqwAlAvcNLbV+6tsP@GY;g9F7%K|mFN&^t4SJA$*Ed8`ou zkO<}gBu2o%P=t&+2PX;#B8-#`H+k9YlpkMmT(#rf!|6_Y6v}gG?`*o9Z89eCxu0&= z?!ai>0RybNt|zDD8olXQ1c=Q+tV>uTxj%L%8g`Sn!xw+$qw|kH@!Rhha<4~=44|q_ zwgXRSO~tZdV4o@Pn%*a5h)j%4JrFpts{@4R>?RqMRDYfLL%%KiXccmV)S@G01OHQa3jF3 z&5n2L&Hc^$_VU~M{mYx*zFJS);qLwFppG$ZHv1A6m*ak)!FwXYq;AbRhdW^)5gHTK zq>)4hH$r9)5aV%zZoV$wH7ElFb`xkAj0XI__?!O`1Xxs1~jvQJ4}kXRQlHCqe7nPls5KtsQH>pU%he zYC7NL?PS~QVfWE^_GsE(1s?9+{pPE0|LjFY8K*~MDW}sdXf*6u^00Yw^ZuKMn|sRX z>U{d~&;H=?XSWfXB6R*KvQ5V06YZ6bfMQaz3QproKCL1R|EHPy=h-S@V8Z@7q`3 zzq{#in#T|CfBXE&c=nfmFRl6g>)#&lS0o!G#@$(3f3yF?zd<)2zWeP9_qNR#L47`* z9Nnw|_H`j(Na)Cg{mJ#T_T}L)n@M=LB_y%d1ppxzox3nOvI9#8&xMx*Gf6lga2|YC zjSi!PS#F9N;H(VZJ7E(UCx&I#vgHw6c&OUOk<)H0YsaxX+$}`n0-;J^)?u^DXM=dv zf-az`Fb53)kO63uVZ{*QD!dU@CH9VWl z3Cr0Cb32~uIHdpphY!`!*c;^JKmFnJ>G3(^7rYPdoIFS;F z8AZ zdpSPL>Eegs(F~@B*Qdr2AGnM+cA;KFbV{fpt46?Bqwl(!i>!mQ+SX#AO%@;1PW3B14Ixv zXh0fa*gL3bH|rb*YGZo(B%ZeM@%o3}51dwBiT`tF1E2Vvz5X}O!< zzJBxF&FdGhKz3!DCFL{?_xHDJZ#|$p_I`i3pQqja>7(bL{P;)LUz`>3`|n^FSp@4x;2p+{?!v;6KK{pIUVcjLvg;X&WN z{eV^r!<4QLcQ2p+{^x^y^!itS(jPR9;u?y6&@hd*EV*Q>Mv_PaeSLnN+r25U=hP0p z@v_^L-Vj64oeBnqIknb|G53yI5o6pXBTNwnAWXe8qXK~iDF9*w4|(l8%0SSSQD|3S zUC1~trZO>#@P6aR6^;lgN!d;EDo-VA#nz2Rg49 zyI`kar;M-?q=@hc;*QAZEf@h3Q(#O)D`Ejg1Pew7Spx*veuzlCCP=U;sCuvFbYO=k4&B&6%%-OGqhffi5al1P=Wxx?7UShTPD-4 z;wlmZ-~`&B0t|UD04FqCazv#w>bJq82T>w`$%FwM6Sb}SqD=<&FJJ`Io0(q)pgWlT^?aKb={2+9yWC?h9?=pjS^ zfgBXx5!Ey((Cws}^l*QAGtYMqcQ^3%ZU6Qzj*D6ltaZ5BZOPA{?DqR%!-VQ6lLrei zCK4hH4xm6MDrrYU$sELqlPjl0S_9!PM40vj)?+miaK$v{g2w;(U;TH$D<;Nqf?$en zWkf<`LWh76bqNkC8MU+LpkP3UA@pP|RIAOP;0~}>?+UIpB{-jkvCzeshbbok!ht3c zK^CG?Fwc@VffbTD2pPK(MwPKpZw8HMKtRj`Bw}CO&H+wXhY*Qnw%J2Rn}+k>|McvK z!?fR?-hKP?|K^{)c-P84-u>pKyD#gKVWU}^zrOnDqaXh0^4az7(uM5d&DU>#^Y-y`;6?bE_+v!>}c15`z#)%ueSQ!{Kg839!@upCUZ{wQkGq!@S>U=A3J- zz4tliZEt_8B~_#tlZvI7Q4=Q!kS_uJCI4meF$fSif#BFMY^b3vJ2XYAsOoOr=55c} z&01?VV~kXu2iBS8_&iU;k5ep)b@kq9+pb2Ewy|~-?e{N^u;b|UgJT=wCaPm&5n4^F<_Vz_hm%T+Y# z`}2S#m3X+%|KN|lD$g>XKTtZ1F=~BuaGEg9X+$H=;alWPKH$9}h^3nmF_MFrklZIC zivWVVK~jm>Gr7TBw3>t&5e*K8SqP#h442uhxfawlJWGnfDP`)7;58o#I`yQgo;8E};ZXWOb?aRy%ww0lV1hSjp{yhEEdRwn`QHbK z=7Y2fo^*l^LL`^s1>^#9WEEmi0S&0YI$@C0kf7$*7BT!5=307lxXsJ_FzJ%%J}VKW zG--)6Wt|T!nQ3yLl^@Bj9HylH+&Y22Q+a+rVp{rht@W=l+i6FX6iM9d~jDl1zm2eh#xX3AM3 zrRntS@bLU3xvU@8$H$9vYSyzJra3Wqe{;L7J(@X^q`Y}E)9cfv)uA-sKTI#4eR_EL z^4ZJh)BT*5i17pV{o}X);oILlKE1#0qdwk-P)U<~`ICR})t`Qyzx-r3V%DgowFb*Sh*9C2J;? z;~{4y(xl*^N}}jP!~?JajuC05(I_Zt149@<0}y?uG&6}XAs-wLIjXFE`b>F)OkS7< zC)-JiiA2|!7;Uh(KmiQG90hVCB%*K+p#&M>PJ`J72?L-QP{kmqQh*TbjSw^faH19l z(8LIifF2Q@LO~!1k&|hd5lDk5*y^Rm^TWBa&`f63d{qXVq zxxe}C_08M*v34IcsXh}rzAA^Jcfv^mNya`HnK&Xm!o3C3eHt4lmE$ZWO%s<-|AC2urm#+^nzADsn@WI$V}Mv_0z6n_?9sbS z_XP8zXv2d@X;_#i?}pJ@<|WJNkaF@xM@~9Tnlf@ZutbvG_^$Y{VvNpEk``WqQ-lba zIzlNpAV-$Q0g7TI;Q`xXCu$(o;UyoQ@z1}`^VH+?tH1i2$IEp0>XZE0apF(f^~2wP zw^rEt)R_l)zy}d?$tB5jcb`BYnwC>JK9_M@4$qF|C>YK{3RLCNd7*_CD8*6Vir{rU3k_Tk&N-~8s|_rLr0n;+Km*lv9vak(_5 zq|W!RU%dMA_2H{emS?*E=KSI957!o*Z-=`V+zH&LXLs-(94z9^qql8bmb+s)-IXM5 z-Du?AHwF_5QZC0d9S;(0TaW9tEHfWG@nL;;vHo#-{(M|`f4rT~7ozFOaOe2sr$0Kq zbba}A{@u5a>&GvD_Gj(=`OWsbuYU1)I{oa2fB!!}ez*}F1AB8sgsLzaC90N-65{i_ za=EoW+5Y4T=OH9kiL6`7W=voYL3oValCV!CX%XF%6v?CxR==&zhm0_EibMi3W)%^x z&yMr?=^`8x$-eI|Pe<~&TXfNpit5C5YfsnR7^qzaZ$9Qi9G+M)>gnNrQQ>yuX-WgE zk!%~w9a-}rt9|dW2@NSH9fy(@37Ch>KqE@LD4D~=1H{5w9AI)wN6zp85@Ck%#2}j0 zDX|k#MP58B3r!Ir&Z1;hk~)E>AadrxJSiE{%-|@HW>k{9LuYUiZqb=oVIUurC+~y8 z13~O?MdF0!WR%(6L<=HhfZPFx2-qkRNheoFC3b`bm{NgsM`G&GLJ;!ZSqOjNa7vmE zlljBZ9><5r@9T#T0O`17=6*eYc)X?Pb=@`Ews-g2GKnT+3H5cmdFIh-rySYhcTZK7 zl>O`1`DcIni74y&`{vTaw{3tENV7UXI!u{Fj$xxa(8I_u*1^R@f+^gQTw?Nm1DjeM zk>CdRpkxqH=BPqy<&;X%m0du9)YSUzMqocgw@@6Mgl1Ro*3 z5J4t3k5MJWg^h7-JQnwZ#_#ek!ai6~sj0Wub?d8cbSXz~^~zC%_Apo0sGTr1Mj{C|HFHYA5GAr9 z0$`%Hhcm(@%tvJ!A%X-ohX8Bq*fH)|L1QCK0yt@#Pn1p~p zir9h#G_wXcXT^M|`PJwAE}q`LiIFy|2N`a%t!~{&Xv#FA+Ta49S4nxh;AtC&!|X~W zADa8yOO#;A{`IT!^`CqZ#CZ3nBOy(-n^HaG3BvFeu#S`Xx1*fYD~Tr#i#d_^y0T~M zk3uuC>lh;HE*hPP8i>P_1lK)CDBO%$I*5?TdySybg4TkR#oUm240sr^7)9|xHmtZe zO3DP8+4{`XNm;>Ovu4RINbDv=Nh3ChLM2|jz~SYwyqM*fB{3%^Jvs&u!4nwjOyNwO zAQ(v!h%KP*M(ANanxLNBI@;sfpKed@+T+{XyC3Z7wtJeBk7dSj$@h0Drd^ojzbZ8!u<}{jfm;du${8Jwz zTH|tXsv21}v5XGmU}t6!I9W(YWiK3-CW#o7Cb7+kW8Ep;Ut4TXdnd}Ua(A2;UdSco zxnL?J^PG-HWD-d-Rj`wuSR+N^v6?%@#14XhdsreeBw=IXWWKqc9H`{OjL663NyPeQS<}Ry1{O!V+F18!$y_ z37LsSkPl0*?S9S-O)>BNvU2CO&BvUM`S$L^<#y{8)#_7-n+YK=ix5!|D@iJCG@az~ zcx~q19XXShZQoCK%W|3m?BT?!Q;&n>l%C#vOCqJb`1tf)Th~2IQks_gRM6^{Jm;gf z)~D0KRY!y}?q0oeZ>lsM?)q(Qv`^EKG$qb@WCH`MOfR>`?~)IU>GJlw-Z3pxI?6OH zr}^PD9j^WD%P+r3Z{Fy`j=N|38-M%uckjOWzSWWJ-RFP#=jAf}{+EA!*;?zvwhA9) zJx5T6n$Tz`<_pXrwbiC8+-b=yOOcD)@0g4eKY_$f=LXvlnkT4M=nYP*~ z(K4O9G%6)c$+ugkoYQ!CcDimm6YVTenwI&LOD>672^gF4%dm*d$;4v%be7C zIizQIM^>bNpP!O0H7S3+Onvl(TFbalKau4CH zdlo7KH3;rB69y5%ln{vKC}3wF03k$-JXYcZiIaCG2aBqeg-F^8FKke1&_Ot~N#XcCC*tSr%QIJYr8k~8*I^7Mj z&ZBTL-V`~|6;y~D3HheN9dm>;YtHC6BFuu2LzKHw8l#6x?1p9H;l0ItVV}8vBsjYZ=4i$H&6v7;O<#kK6^er7dbp|%FxAW zaDa%39AU)8NdW^ER*%>a8X&{wLq=;cuA^~W_wCYdAGYgx{qTc*{IH&Dg4Hya(=p%A zbXcY-B}gFHmDPqOVYmlNH;{qAs)xII%3L(Flcp^_`y<-k=TV!n$AHXX7B#FfOQfX) z7bXIU{2#yihyAv>x%W+zst9;kB(m^;m}{OrdMd&Z2x8Gx60%b35j<*jq}${Bw%Xdq z-o3CCYsX3E`;t%Pq?Ge9OVgB@Mo1EINzXCu9HBj23P}o&m=xYUJCQn^Lr`Y+Yalav z_)KF(%*>al((Go&lEa^$&QJ1p|J}cR^CtcN{OdpY(JBA&SO4z+`v3mbd#92C%hMb( zN;yQdVMd%SIyr82Z>{t%@c(_|HSL?ew3EB3zueY0TyXNEk>^OtA z$IU!~JbX5Wv*)pn``1V1R_2HMaw5r3gKoe2%_v0r#p7?k`OU9?Fw5I``uRWpS^Dgc zp8odl-hcPjRifn3B9IXdp}tlqO^8pQ(fPcM-J+yMTMN3+c3GWl>#F*6cEB4(ZM1{U z66zpmateshQA*wR%dIg_78`f)3WPW@ zLM#T9QfCHdHhjqrpi7=Ri-IL13NRb#UfDwD3Fg#qKnK4R|{4g;8*uMSt`}bGd+Z6HP(sgVE zHWv#|S&q@?WpbB&Zz!o?Z0^b9%`JB5f$VgzU%ozk_Q#*v+U4@pBaN{)nljC@j4jY<8jwd;Maadj* z%JG@z5Mjzf%nSxbAd`b)gakN&dH@UpdyL^;A~ql4yZY@`SF(5SuaEo3vwVCv&YgU> zd??TEj>{rT;dxR*bJpI%Mz~R83kwSk33u|8l1M2&Q%*B$5*XX{BX!>+Rr7&jw!_`W z(2`~5l5!%)l$Dgv=iB*w+s>DIixJTcy~BnhtAK=ps8TM>6Va5)ayZWEc$e}*6N6a_ zu@SkeS7FaYHmvtfiKw&0pp+%CP`EgeCSoQrtXPR8z+ITdka(tO!a^jODZ!BmwjpJf z6w@NoL?i@a6F8?H9&x>?|L*(P-zI+ba3}3T|Nd{k{q4W`FMs!84;3Fxp>@A1R5c9) zN5b$nY?V12-D2ymBc9$p)tf2N4&8R_bu@5aD=D-4>ETtL z@|++1)}OYWMmP|jNr%CCq(RBhnE3hU&t8A|QW&RtJ>AAk0Xe-z5S@%iSrzyG`A zSI@rs(NE%-dr04E)M$J4z;+qY-TRhuuq-ji$m#kaQBJIN-)&Ux98dcI39}QRrCBG9 zsT7HlB1tD}R_>B{!<^OkG)7z=hk-VXx-rDr)(S%OFkmQX8YXQm;iseIIcKX&qD6#n zR@;z#441aM=cx#d535%qE);_;QQf)OsMJRrUXORvf%p_9HDdzm#wn3ZMuMDhSVA-T zjYzl$S@Y>+J}_d0(f$#U__iSuNI92|f~}z>h?6%0Sv5G3!wBSpw9vTe)|i5gsXK*H zt1uzY1RbD&^QdHU(M1F8Z@XkhHbBQ=~w(2ywlFLNl0g3Ri>_#LOsA(3C3U3aM zAdiAEQ3!~r5e1VAGRQc*Nemv1Jb=X3g9xNBqfo*0BJ0opEdAo2{qJ6X_FzN}=`byw zQtiF+Y8!QO^YOZ!=mD_e9)yx z2C)%?J(!adAr#@zL?YynXrK%P{Xr->F!tV)4hqbMnQ1|Mi1Ko|s9Y#%)5PN7DQTYhuH-}J zsZgac%vfStS~U|+dmAHq-G-|0!ik87hk%qOhr`6p_7E~`WMrhVOZP@;A|fe{0j|N< z?y;CA>0^N47s-Wb9m^-T-(5cbyZ@$5&(mpC=fD59{SW`oU;pMjIGlqy_T}(g3cGdI z)JEM~gsZljC}z@J9 z8gKg*YUSCp`FLVQ9cSyU#io2$->vVy|BX$o&kpHWKzXBKtx8IKI0m|RkPqsEK;{1a z*%v>Wj|ZxnOQGBj^XJz$-{jFiYkPlv_s#9{!|z}H2w(j3U;OdUz66nswEpt9&+f<9 z|M;iVDC2SotD`=S-Z?BB9&H*5tB#tKy;tQ-PZw$*b4r@v1_p~JW}(ZC{6?z47`L6; z-q+hyc$)KeyV<-XqwdmrGt)*e5jU|u5Dpei8NpMTTW^s$NC^fjNsg2R^Rv^vJRAs| zSb&JyMt9NE#Cl3~5AfIrNUl__yYB&D+%IXF^Sy!=SdQo%ZrskuENnDZL<@w|fC}kC z1ipTZGKGVX5fqn;=X+>|F`mw{1<^!M66Ku3Be`a(&D%O`@zJT-kPZ=w3N6wH z*-E`5f=2V4LPvB#C*cTbVTeYK4dFoHRlETl2%<4u9HM4yWX1`733BfeFz`e%T!Ohd zZNU-IEFw}1b~1Aq35Qd_gB%D-08xklLRiRHWPW|mKl&G6{rNxt&!+pd3k@+&+%#EO zP)Nvzu~#5qxA5V&9{Y0Kwu(-M%<$xL)B?)E96Vai;_B%l#HoHXQ_`z9@1{&J<0!qz zA_C9EG8KY_CSheuqMQ?Yj0pIgQXfW^meCa022+q(cxd8ii95wUQ4?p!&cdvxKCa>c z2@5zueTZ}Pkc&yqq^7V?fsty~FjL>mSDT()+D-S#s*9yF9rRb!MMVrv5}NIXfAGzwHnviRu4+hcG+A3RGgQ(8_OY)VqZh%JU!j&SXoAe5%(kH7k5uX{?$ZY(*^Dtv6W4?LctU(B7k*XtUor=tdS&f==LJLG(rUOfNe z%demRXc2p-e!gC&-~LbkfqwVjzWhA>#b5m8aY+$*du-3se*g8CpL}+VDUU`$R*FzQ zz_*BAVWS22Tisgc0L6eXCEj};Bovw4!_jvy*}FhlH4!O@oN}+-$Iw)yHovV=FBrxP zZ0ufpv)#?O?K)AiVg1^#*TbyGhcqoZ9rF}})D{l)YXYg$M8>1%Q3KuDX1%+8SRX&` zaY7zpeLG**uzZsHG9Sv}B#9_II;kQqKx!Va4HgiMbvI)&(Yl83eXuJ9CL|zg=;U0Y z?~qC!A)SxO6Czqf7$+hg@DOzddB?yAmlU4h92kgg0Ln5UK*$ja)nKK%!I-Z1uw z4~c@M?z_5!`Z7&&oCBn_p#|@od0?2NY0uB2e}qlFH6P~f#@XS?#)YX(u-(1Gn0Fvj z2>Y(o!NrslV}yzjS(QXcv&5`qAR*>ZfvK_?L>DHSQX6h&NG>Xzdv($PIf*3>x;r_L zyz>ZG0=pw1#ABpUXQ@0Lm@H4zuyD!bUW%s~kVb4_odqNa72*mK3JMY@3KM4un6n~! z{Qs>^H;&5GeYDZ6UiWqP^JUyR`p8rmSp=*v4*5_Dh``lztYoTD=E$s*L>A5^m7FNV zV_;%C%bc)erp-b|$KC)I<%Hqj7%+Y)v`{Dqazq*sG2wmP_jNyC&TSprdaKv&x7GKJ zdqXpalZvr3K>=k6GFESSp_I8u@QkwRl=H&`<*3wpi%1~|=+$G}&BfVijE%y{4LX8{ zClG*POi8=3MEHP~5RcH%Y7vM`1KtZlgikPP#^xjLUK-~R+|7^r^PkW(XZ3tX)8UZ% zDCIsA!K+egm#Q!9n*iZjZVpi{ z;A(z;3SC+qkKcSZEcN>F^RK^t@%n{O>X)s{4vv%;kYpX1Xrm`kAAS1p?)Up3n^8nK zm=pJNyZq{h>zg-YYwMevS-pL@1rIGt&RIyO<+Qwhe)wYf(I5TePu2AMcOM?N7XAUB z{Ja0#e+_$c_n-ar=Rf^Sr_;xeW4~SU7x!O&wy=_>4CiS3Xdekob54{3+y{D6;h9nz zQXo2}#dVINI?s~WbxKJ?SY-rp)5J?+qc%x^)?2F-l!?rknMmUU$(YTgzPaK&3SDv8TyY(k!CH7Ou~#J=G`O)?F~29-bd3IV@?W zP~JT;ca4z)fQakN4k8RNxR3#K^gIy;M+hstaR{OjHmIruTO%JtM{1VQ8Hn!OH{!0D z!n*G%z(f!|xvM*)N0`G0L`^p!Ty9~E7}3p$d4K}Zj5 zkc1XV9wi~WA-pGx4YqnHAq6K#x6W{nAz=(uvLnL4Mne$=@CXJoSOOFwFov-chX!aO z(s`Dze!l$dKmE(kpXV-cJ(4nVLX(^XJY{gZhMS|uxPgL_sFsBjrL2c39g?B0sFhhp zu$dywefuc&CRzfXnOO>@9LSmLQk2a|FnbRw5o;US<3^?UoQDQw8DVA}9FkS2alfcN z3MY_}rrP&ii*r$Dc%gocjG-+pr^ep)ebAkt6$Y9+2K8G`u;q@}DFW0IIPsPaB-uv` zM`O{D&eG$sNMX4<2$PaBtCkt!U}eef%# zxwSER8zp%+k*q0rI%+;7W(;yNAI$63)~j`^b>Fx1wwrab2yVk8E7Cv`VnU07$%#BC z;-orhb}E$EB_>g!EF~jYlT3yncP2_)@~nXgKAi8Po9Qz|f?2feNe~_3U`I0skvazx zHDVSmJXVWNlSEI--Ni{2KI7wiVvUM4_7|Vy;nNrR{_XnleI09W*O$*;>D`2BF^nW& z$l$)Wh%~B=)<+t_I#Z~qpxHbD?%4${VL_uuPpPoz zoXX6B^T!X{R=b$CwCndH>GdluCdWvpe0XuZt^IQC?;q>cE>G|3U;Wkl@BiEX*YQRA z<3IZOGs?SLzut=2{c^-+d%K0(0GW4$`EGmN`o0gcvAOzfLXB}g2)M6#{TTJ?zUt^` zThx!`Kz+NRtqS+YCso(2yM@M}T7yL?k3QIYpeAA1fII5GwH?H6zFx;&hAO8?r%a)V zY?zNBv$7O&V(p=9&3p7#$6l+dtBn16+rwne6PHw{Z7`9x8*L-);9iNGbe4!@)q}`g zYeh8TaCOr?Qo-S#gDD(A1a%WafRvzM4&o3PMzFG*bAn~p5)p##0+5DXd0eGBoTyep zgm+mxc@3YKHX;HB5r_7W%mgO_RkBK1q9ly7phxdwTf`vTX*B9&aBvG`j-A89Pwv9h z2`l*)$ehd(Pz}b0iU;3y2==G2P*MI)` zi`n}+dX?^7nvz{^*ITpA)=u6ki`~##INH8Ru$mvAD~|WF)#^6FQCpx}F_wqXHzGn< z_-Lc=R#NX)eWbhH)z=Oqp`G|tas?B-(Z(!}olu5=&1kf?%k1TTFpnUz5w#J`JZfXG zQqYjHz+?g&G#E&l^5}@3j?{+LqN9f=4|p@S&YYQB*ld-@YC(jZY#=8s{FeY|j54(DAKBD#B*7f>se_V6jBc?nZ^6_q- zQ%bC8t|G44REM+bOj8MSo|Z^S=cJxe=`;CVst2u<=7|uiwOj2Q)jE7%d-MQtFk(t& z#1LU)g6CPYg_L~;H@D_it2~{bdKIsba}tNUhmr(y5@ccnk6{o#kwr{Q zc}~5Fo1^V@wP64@(CS332i(#f(i-KI`W4tY-Nj(vHwPjI=0urEJ0l1g{Ro5)bIoBC z>rPsG?-8M?QFi8F-&qTO_t&Yve{om#^z8PIBKC6kFvh7*Bc0VbnAw zRz1Z@+^VbEFrE1M{e$?pokx)KG*RgF={ktYS3j|bWp7t4LNm`q)CV+|>2AFK?2EhOsanw>Sp`zzq?%CMOH~V)=Dz<$J_bC z6?L1B_bCZyt?T>!yWfTcrO@F7idpOZ@y%_zoNrfd;DEI^m-)Z{FaPa_U;Qug*(ayd z;t`J@gD5XQ`nup#Ev>Dd2sJM7rU9umY%;N$%LcuNE0FD5fb5)vWJg8wd)|4 z(d4@BLzhN0Jv@|W55@s40<*eN@TiZ|;gs%=C5aG^Mly7NU!!$qB#L=vUpo;~-{@GF zI?bAvOl3i*v2V#KcEf~q%>xhdcN%W9VclN6s#8 z`2_5+Vwi@`h;Uip1I{!?7=cC*fds2y=TPGPCUlA|0GJWXtyE`n3f~)82?bo7l;tW6 z_oE91XNeSYA96Ih!WNJq987@%YLFDx!z!T%QBV*W5zxRM2nv)S2^_M@tJnM2|M@@q z{OixAq;9f@h0nLH&gwE^UOX(QHCLJGcB_MV*d95jaLrhWM<2aRjq{M>G9s`JO(xkx z{4mcEWDN|Y8P|(q65=L;*42BZY%UIuv7u?=7F*>c$U=zRJMCAu5Dg#)YPMF$1Tt)d zQMeS^P>!+JWRl#n7*qDTi==d?oLx+ENt8xniV-w|eGni>;sLI#s!^ssq^N44XS1p! zJ-7!^IN(vp_wW%t*f(}32S5QOM2uv++rZ=Q>)Xp(taM>t!-_Kx@YRzS4qs? z2@$QqdtV!olT;>Sc5Y2ZO@ozNLL@c@qqF-u);?lv`?|WDF^nl?8o@B)mLsw-)y}qy z4H2Q*!<3o8gl4vTyIt1nt=rRPy|-J#8pM@2F%j%4irpK-*u-QaEJWx4a}FO@ zgcCNCooj6W;j;h7e{*^K{^8T*boZs|_WX~3asTtzeXpa9UT>=pkr>@br|uPfbhk;l ztuZcb(CzsrukT*GetPrGFt^?PwmH>I#hYE;z9Et744K4Tgz|w>F6b_jg*?YfPoez|P#KDs9@bEMtp!$u1cBD_Z*!+-rB+aFplAR^NDp?&-8T3 zGD^Wbl}=VkFW>K>BL=%rk~|*{nGMLOEi{YRh!mkAHQ2(;M_6k{@LfPG^$M>P8cyI5 zUP6R;3Ia7VRFP8pm3reKQ0Eb$X=o@D6d)O5YG z8*3)n$#-}sfVhT#63IHnOag4*7} z=7;I-KmSWIYR!#>6OYDwBnxF19=05nlD5_diMI+$s_y#=micf(RLVzR(RHY#;o+mZ zs!MQ=Lc>M66izPr0Jl*LnFi->v)AU8IilHci$rO3GgZi3qeUo>D>NsJjNa2^+bZ11 z&k^Eg+F55G$#FXyC$mdC@7}9BNm~(V=e$=mULqwaQ<|8UB!^NK(if^ZK?~Ck1}K6+ z)Pst+6C+eYoG=hO#|T6i*n5zRbp%IL-@C8%_I7`~*6Yn&MH%FnCZ5QaWttPYm36>_ z1`m=%GBZ&mSV|;JV5pLC&)Np6<+0&*S*sjdc=(8;V6CjfgVRz_k|t!OA%(QW7&)ad z;TSze$Ef4B-#)Il4{x7-c&zL0y@i(ObGNWE(R6SvPR>j!DP$p?p`1!_fu0UTNLj|% z#s2_nTU(liZ!H$@#5O`yqK8jGEnMMjRDvajm>x%)%{+`Lf{uvk=sL*UE7+OLm_zHJ za_5|bHjnVIx99ZTzx=mv|NimW7k~2nr$?dX)z>z!zbl6YQp_bWi%j`6wRSD@J&0N1 zBSN&yyyWHOtIs~X|IOvY*%FyJA&pB1^{N(FTKY4XOAN#FtPapQ%74A+0 zqwHSKmmPv>s)vW=`RmVNvR^MsbCPGv^YQGHXD>hd$;Mt~V>eS!}HaqX<-9kAQ{$xlv)JCb4}YK?Zid;9D2F4OC0Ukx59XhvT? z{j?+}yDg_rEhus(pM|)#pe1+0yrh{`5|u=j2qaBp?3)*fC~@)BszT7KJCr*iymkNZ zgtg|W_`WvsG#^r}>QjCCVT6V{@odzC=MMIe)7{Kv>hm&7jGP%7{% z25aaX>t0^IWG+O5&~@L^)|C;-I1-Bp53=E=G=!3nWN~nweVN!gWjE@?Mj7n4&;|Wt zgbto$XSdC10+Ew&N61hKS|;qqn1WPgcqwKU(Z~j9#9HCb`wrRBZ|;J=5xUD}c5rg; zo0Y>z$4CR_sKo0YjbIc>g8>dj1A|J!$_Ce884`yd&Le&^L z8jK>gK#pEz+pKMzs97FuP+d8*fy8QrkS3zo-GdXbc56fvsar66wc%Y;>NOGz6Vg3f zbD%MC?;+|;G;}WRbtGo8aPQYv$(=`}GU#xh=QJI4dU3xzm-*BC<@F?o7c3G0mbsiDhz)L~iULiiBLKc7gk} zP=0A;@;LnFZ`W~}Pygg$`P>!stAF|b`0aoH>)uzA5N7*j#kq$^hme zZyjT$2DUXbEh+Qu3Li5#JN4Vvhkgxx@|M*8=pO%N` z-Gx+pr{HOgUGqevN*kARx8a)&VHAnyFYZ0N1feiuQVs?OLc~bf_lq!sQ>3gE6s^n2 zf`Wx;cw-%15FCjGzC*%-5~s{1~k zZpViQnYb`dpc{Gul6Q9{iSuRr@OFFi-7l5n)lWb9+0TFW`RVoThwsYiJ{=}g-qw9R zU)Iapcfb4f=#k5^93C#0^M3tMPR~;|qCVBmQ@{JL;Qjp?Lhu8XnYaF-8r)cZ)EwY6EKcz5o?=jP3IQp{o`5V4M1r3j1+)bh zlsmv;bmJ7{-Uwq0ry%t(28B+<9Noo@!eki4!Eg*Xht&WRx9_Vu6s`19@K zn<7#zJdv5xu-N)YbamQC++4$=kQ{T)rvq&_CW`cI?YpKsQieCS9b-+B8Wz~fBVuel z3Rz9biFQES9F56%5)iXR5=p1vVCCXFmlClts?ZW3CL?o%5mBnwE(^CVaN#`|&?9>A zRKmkz4Cf(+wfC(BG%*E2II=SS7WFeY} zgRoHuc}Ea1$Zn2IVdO4YITYg-t-4KK!)~{}dtJAE_kFc}ATiBiNeXM>EKD4Pu9`sV zQDU3QP$}>#<2uI(Nes$H#6yIV!O;~%2gjuo91(O!U5L#@h+JG?F2t#&Bky%A#g=EN z8|8^TsV8NY;b?V)PcF!Z(Bo(2i^bAHnu6CR0K{GRkDj> z3>{A04|$QgCUOST@W3tfz&t!Rcc*L)74A$a+}Lg8yH2yEgr&vAA)pwvIa3R!t{Zt4 z7Dne};4r%;(zhSBcmLo2@%+O_DtD)c*S+WH!%3zC^Hjp!V{@f0L3=NUmwtXyqf!ob zd0ZbaG|d6#*ds`$(%Kd#Wr~Q}`{w58X4X29A%?S_a>~b~#YH_&mvuvHvG&7ZaUN4T zH1B=egr(In+=D|?5W^!~*ZS_fe*4`onfl$s{g=%Qg!rg1!IKw8^sXRTqRn_X*f+qOryG~XS6`sMtbuG({A zg-W-o(N$2E4DDODmZF0WGm%0|iDo_aTr!gZL0hm!W**&^xiCSAqTgh1-8Pcw*GN~jaTAMU%gc6nRhZ^EntQ$n_P%9c4aGYUwL5p6VP zVL428+ik0+S@xX}7(4AX_SKQ$x6a8hA_Ui~3A+<=9^HtUt+II_;c2J3Qz+hMJz`}*+K0gbV4}m9u2;mB7i4hz#1q-PPy?B*>`p^F9t9#yiO`=<^0T7qQ7W*(W zL`(DGmum1kLG`8&*gLYcI8a|B-;r(3rbJ`nm5SM=2YT4H0W7h<9~`4sa*s%4Mx#R`X7+ux z^+tCh+pR~X-KOn2-Q68dX+A8e+{sCFnR$AUCC7Y{WK7W1i4Dl$6f_eBr3@A#qY$tM z2n0ukOTZ#DXkdKwps`kay7s;HbF@9!X_}IxBz?^zG=kk^nu-I1lkY_*Y2iR{lHM&b zbN66^_@Gg_wcbWrBU;~nQvsv}M=^@B2tjel9<(Y_8 z=TNtX^Sc`Rx&G#Ta)*Nl3TNVjicra+sT5|eo?1Xi41KGY>+QqY+aso9Od4r&vPOP1 zC##{8NFYdb3v5^$O^ZV#_8^UzL5ZhCxH1dE&=A}Z6Z&fM0C#8?PfnX>APGc$ID2a5 z@8k5lfA#j)zkmAiFMjd)&whNqT`Pf{Y^%93CFW`3UWGM8>2fpMbfziMHg0{M5XR(` zRfhnr99}TD^QB2SjHUt8sfg61i<#`8?2zd$-5>R!G4^^rlWLmFcD)QACkE3vTKF!Z4&YO$Q&%SV9sPOd3 zr+1&e$_Jbsk593#k6-=t=U;vGqw7}B>wa!V)b#apE>rXv*R$>Y_W0H>d%IrN?HVDy zlTpeHzfrC5D%(JwX`b$!$Ra`tjlSgtB(HiR3H4mw&4RY{91 z$LaM$xqq&Q1d+^Hd7K^|4s%N2={_4&7v8Q<<7(};mts4hGwV43AX4YOdJyn+Zd};jL_7s zJ%^PT^D@nu9x@I~nonuDr)f#~be|@bbjnlW@&!*RFgb&Sh;|bP3d4axB;gWZFp(%b zhp~<3ng!W9^>z2w`eyq_?CWTeWhzn}(PAocAW?{qeQz>4(xAz5Vr2^3Q;-ytN}wzl z7TpYkyoy)Jol6}wh*MHM<#bRd2ajnI%+$LFb@S}o%Hh#FE0Y&5nQc@XwFN~kd#fXn zpoh|^&4-T|Hm>d-9H0-BmvANPohC`{anSiB5tfd%wz_$@95K8j<&u_3M!R{cY0lok z<~}fr??i{ATL_U*@luFCl0|rzSXezmf(AT@6eTNl@0qLxt7BrT+`5cl5t*hUTKMqp zO`Y`RkN)|eefrsLk_nW3Vj+#(L7>XWGrJ?gd=HO;`PR1mx+OPWcZ{k@k<40Ped=v! zNs?z0KRvuuN)2;2AK*EsXRq!L#|OPX4o6r|(>&_F)zzC*m)rU@gvT&dr)2{A8g_m1^J=La;{cVy)2w35Od*`ot!;<9 z10>8@xhyXpP74{SZ&w)2^Zj1ev9H9j=cGBtn`=G4r4S-HEXgWh-DGm6@My6I+WO76 z<164qig^p63!o~Yg;#^4KCMG2?_ zYmBB?J)LN5bUjPIDl?Udyt)$i@MYn84jUXhxUj5BnM#emYg@v1p?i-#j6H^e$Rq?* znJ0DcfyN-jfFhcNkjD-j10C}b=44@cj*;BEB_WSU8YqrLJb|?vf&x@Q0rf~6M&TW3 zE&^@{F;*i1dLTk_kXR7RK@y&fvS7(F?ms#Ge1Vj}b;7%aKgHFwz(imAeDAW@gOCoaXF}qp@`n zo~N?RK25>XAVlBrO1kp*op;|_&oCsvoq*E?=_M+hdWfT({mWM_|NfE#p)>>~7 zR&6+0xDCoh+lI@|hdCR|sBmTm84a?5+^?07he$GPLuVe2;YdtsgHocp?M~FO@6CW= z#Gc^|!<7oP9uk}cBIcq*%xw(cAI}y#N|O1`28gncjiW?TPXwVs15{Xwlc*N8O$~&B zBxz^k1BfAsRoIns;fN6D05vpw8hLe55Cz{LUwA3OMCG0cJo9w-oKc@2POl$6p8w`I zH)nZ%n)#s1LS9Cbp4c5$=Cmwwe=0BUBZqZsE*pjAM5&C1lrv#qE;7wt_i=riG}YTx z`bAUX}%Y% zkmB=oyUF|C{qA?a{pI)H{qXkb*Zap0^=Y*h?fU+B|KgPHx5slc&4n|TalKwHPdOi` z@9p*>X$kRlUl~ZmT!(eiDKwubL`>@CX;=yyba>I_>D}M{PxH$k@#I9051;;Ga^J9f z)_33khqvE+yLoqn#jUd2F&XlB+Sd=i*;U7I+ImTn$x1mAIiqK?=`d#mml+!dR1%@%WUsvnl$XX^WiRRfjh~N+$nE3>v z;Nh%7B5V=aX@m-cok~PTa&UGwp-jA^?ZlLrHDpMly$MsOINW5$*kbI2)Vn%(jDab+ zu~X)Hjb(C`&@AGBj&K?|w17JFNVK9)o|u~tcT7TcW8chLq!Li`iE{M`OwuyOYugYCHSxw1HSH&pKy;(sTwuQSh3CStin^cM!^MA_jqJdFKj;T9vZdEPcI6PK*? z2W+Vb+<3Aa)JN3aXQe;b_vlW?!m35J2sb@E3yR?y7JX|VL!;5!NW;fu1hUZFvJE)f zc5~~^W4~@TloM;7@{|G=XiP-I2sa1k-S}!4=8lNy)lni8knX6mXVO8)K=U};*ojw0 zC0C|wynC5+LMoGR3*!WV{TAU7MB5gz&aXec`_X69*PnCd>)-s(|HI$+ZM1mWL;GFg zgNoG~?G1)`xVf?S+{9~dw^eu+S1Eub60Ca*WXJBK<#{U8L^-EB9eMVhnr&R}B*%0- zm1i%4x!(46?L1}9#W89}3)I*pxXgK;o-ui(a>~>+SuMx54>1%`eyWmeUJOsrJpg?fdEr zd1pdczi{9Cbs#&Yw152l`@i~kxTW-BX7~2^R-cz2|Kb<MCdVuXs@v31>2{!EI$B(%e0QxHLSAL7@6!$Z4k2La0<%BW8%}2(PEIZoO}buD3oP9!N;)VZB$nUDQLnN z7G1>iv4(|jgh^7D*u#vMhuk9oD``~JKo2q}i|!a`=cY4n)US{39>Xi@sHrzb3lr0* zE&_MQ&g7$Aq*c#BV~KY07|cnAlR6h@!gTNXl=8hz&yr4wvO?}SoU$@)5)d@Tm06U@ zLzszUcQwKkLE&VwgaJ+=Oj4N7?riO2+qeC4-Jh`4=;6ss#vn)tn|DIwwzKuZoI*5t zwk;o-V#$evkD{)`6i$+8n708J4<9s)6Hh`#BuUIO5Ak5l5(E;8lww%(9HzlRd#I=j z$!Ye@Ijn}&ZEx-Rjzv<@bpK!oMvsVu(C%(VYjdK}6LTYgb#`6MZq9;OiO5?M>!@aJ zY;6rhtZf=jI#66vi)b21#h98q!Y9{h@YZ`nUo8&QCt?ZYxF#y$WTC{o2PW=jexS@2 z6JiQV7@e6Z@bG+p^(S8>oJZ5&|BZiht9+QjbqQzGOTBqFn7P6eALc_U&zyR{UW~Hi zO8W(?_1nd^26(?+se$T%gGNK!`n7ihWtGM`Q!4rJ{KtHt)<=)Z7--G5E8r{ zZFKqO_h#oG{q(1YqI=)F$YpP%Tie%BcO$~6ruzM_{`R}y{zo9l8^Xr9Lo@7}MA zb;b}`3FWq3B)h0>>&J@Zk5^pJlyZWJ4bnD|#cekm7M00qYcjjfdCydi%4G%3WMpv%}7PWpg~GOM93Hd>qG!Asw2!S<)G{y-6z1p2)m(oP(nD5o9!v6 zr|TKcxW5nIqDZhZGJ0iA@SP=DN`&GtHyhn}NK`TdCKX88yJsUA z&>kezg8SxD1*?cdJdAy9=mn&t2|~~et04fxiO3ub3WqDRQ;Uck=n(;D1V@mC!4Td^ zBM3wX7$Sh^Va*+g76fnvoQwrH9LDqiX9@A@j&>QWWB3@(#3|hoZ%GwWqIBD8GfE_~pBsjS{r^b9uO{2J^i0fq zKQqRdbFQ^AbMJljaph4c6l^<^O@<65GI*nZsUM)wm2{y{C^{%Hq;9G~HcSHzpu14! zoH}m1%v@`lF+QVW=y`bCQ|3&9Z;Z-2v5?lKMx>9Z&3h<{?*?(s0Z}#_F-LHyWM+4b zoQx*w2Rx!;ObyPG%rVWi*148f_wvyscNbY^o@Xrgq?~d|X^5IyGbyurh9i=v6nK;X zd+tO+9F()rK@1AdaU^CRw-{z0*0|9+IG#s8YDX1#Ic1Dc<>usOUK)mLX5kc_VpQaf zBUv0pHC#1@D5ab7(R1y{l$67gOHdjT849jR41r}L`j9cwx2%^?*2Z)y%9K)%JQz-J z3K#|L>(jokF-h+|y1OJ?Y(yq)cJD+-C#6W@(M5Xsgk)a~wODT5`_bu7h=d24dyvInZ^HOW2Xw(Os0{5l0 zsxM z%tD!K-`i~;@0~g8bWd}DsIt-+&P=6kkKg*H&ghw=9suz=D1x1cLrP^*7Dhq9K|<+)aA(p^C8Kc07DuooZ7WMbUnK}R z^7JZVW7?cLa}X0JoH`g>YMMmV^b`AYR@FhUtMEBuP~Xs$xw3lco+K=0 zl2WG$%aY#N4yQmr{PyTWA_k8wM)Ub36ofH~`k+?LXkp)^wLPcZZ4`FHA;tISgG-Da z!!!EQL@6XUC*5{uCisD1MoF%$r*O~6QoOHGx998|MKZ-aP4lZo&r6+8rQKImZd!_E zBPvyLrzH4e<^gP=07&6Zo>C>4a?W%lGj5;&DSW4#d|ab>E80Xj$1&L;GYZlw7^T;1hKF5}!ubpxUcrM!8dv8&f^vXJQ}BQ^ zAz^xoj94o3RTm>C&Mg(lpxyyFo}Ts&yS@oz9(?ShWY*HQ!%CY}wMCvvoiAqc8uLKE0?ldzW0a1Y>yvufY$fa zYgiG4*=?F7B_0o7_vkXZD~VKP5t*h_9uSs#S`4NGYtryE2xgRXRbr;3lSoiEY)Kxn2Qo=u=#Dbj z1Co76H-Ke2VHj;LKmr&h`=C0b58nk)X-3t%ToSh+1T4S_Cl*SNbm8y}P^v?NN92JlGRlD?LMPgv37$-8Krlr> zf;ck*?v#?GfC3X$1v8wI0%{cD2!z8dz?SStfC!l|3Z{spkw`KSG>go4`Rc#@m!Ez* zV~pe27jFR$LqsACBxl0hUJWDROEm9ZZ*j<6v};sdct zZCNL@HnlpUXi^cHYndMAdQWXW*IJ}mEO*oj>I|7#0hzr$BvZmb6QX2B!YDzp5(e=` zREQ!{BRF#pNca{bu)D7uPrhCK>E^q;MY3BIN*1D`AY{0U0DPL8^wQJ%POD9Pw6SWE zbCzR}A7sQN+wOW^oH$v+gMBAqI!}CBC{1*#pg~ep2RM}vp+MSoCEWq!Ex`?x!AX={Pee72n{ST;Im|?ozyt?8+&9m` zjYO5B_y%Lb!L)}N^`0_QY!EG;eQwg8pDn-xA59(ar8dGv_9=YVCYUO#p zJv|-QeeB!w+c(}fo!a{JczgF{kKntHkWXaw^y%vtpIq)fc^N~FZM^yGfBz4E|F5pM zZ>HDf)t~+JkN)L<^RqwruYd0+fAs2d_xk?f_0Ruw^uB+M>#x50_R9}H`{)0=AN_a# zsW8)`!JM;@7Me8X`{}gAauO*jO~{>>OX`&AAaT)zXOTT~ zut3qYV#Itd13B+&7=fv5yO&ARL6n|J0+}6NK&eDZT`4=aN;L^;!-$IZ zN9GvqrE{g+f*(*4yQ@~F;NUn|lJ&F%?&;W4;q65xFgm2UG=dC^1js>tC7ER$lr@?l zJSky4S)-&!;Vm={SWrfWL^RGsj1=b}QXxc=yC{J%0Ced+!~v!ZED2pf|h2~RIpQP! z>v0{cM|G8*tb>cn!(5%7qgT&WAYyPQJ`T;Au^(|tk{rctljE6#eLM?T`xZ=NOB+V} zkrwF6V{r7e8Z@Ucj?6p&5LE}sZeXsyvnsQdwrw_ic#vZM&~K|s8K7>hleS@`CLY;1BHRMVW-O2hp=1hj#~q6r`hu7FE*B z3=sT=oYrR^mNE{;Foye}N{L#+7_CwkZmrg)#IYcF0#QPEU_!Xpl z^$*{D{l%}}|NV3BnTEu*RVq?SQPBwz{=D_E?lG{&_Tfn=lr)Yj)xwmrheQsG%elt7 z_hSdCYLQZ5Z2kG8yU#!Vy-$}{EQRdYyzfTIcV^J__Kt2V9=ksu>+RY4u*YW+YIjmX z)XlF~goPbTsS~1qxbnCrYCP}9*s4x7L+2tO_g+dJ`@Z!@+Pm-L`t)ws=N;|w`D(tO z?#{xH3!feyj@#q=Z@#`h-~9R%J`A=Gn(khP_2bF-axaW_;`yOyeNGzd*YVX~e)X$= z{coOr{oC-{^u2ca-u&60{)<2S7ytF||L6aQ`#<=8T=(N>{p;JOpZ)Cn|Ll){^84-6 z@1H+?_0c>x#eTVaT^erd%GYfid5fK_@BZY6?t?68svZ47tBw&RVCXeO&7_ErOv{1Wh!HyUrv?94>{y(6GW~ zA}=CzQR{TuyGFNZYDFPsOaQU_5lmddP*@74Iobry!4q$h?1T*!*(Nc^a2x^LNSD~2 z4xVg&CG-K>NN3J>*^j6iX`Gugp$U2T?OCvaW=iIMNF?Y02}h@38P5!6e@jxbKQo0S z$H+kbFXRM1QdPtv$Vh1G!A|IUtZ+-Jg&4n+W-RH0r3D*^5;Zk50uYW7euSLJ2-v|b z`$%MFP^=^pNy(nUNu9_kCP-4cqmxJy6AU&;kjEO4$&@)VGIND0K`Erb9$w8q{NWFm zLYg+vS8Qh9EfRw?mb)35L3@k}8d3U4^dPxsZ}*LMQuaEWg;<@a1>+c2iybLU)VG`$ zqJ%d(&7?YF&73KcRTxZuXe1(&2&D)$u`Utjl2(LD3TX)`Q}|KbiuLE~(fkQovr31KQp+(?C_a-LF|Wn%8cEZm7Ip&$U7gTaNEiHRA= z(6pPc7PoF2?fd8-j&WoeTqr6}MI(9!5(ru?j$MK!Mp%YuHlZxo9%C?#E~AGb>F|!e z4d-fnWHJ|rOctz`v@D`vncV_|xwgWb^F;~NCoSEk)8Lvp>^x_o{n$COM|L_ayYIGU z92OBdjpz4e@)+EYBdJaVB`JOgI+KX)86n%AzKW=5EmKV@OeLcnZhq`$iOxu4nt37_ z&)_MuQ9(Jb$YfN?002QICIqFq^Mn|P2pFL-D!CE2Ov;qlg|;=1l5cOh z#hN9@R@%&U>1bKY{BW?gnIEIG?JdWH9Em)`h z`Kp2lWQLSzMb4M|X%d}vaGhGIt)!fW<=9519)$@#jk2lb@Zh;M?|af{lZ+5!`W>+$ z9>G8aYbGc6XQJW42Eja09%E|KHzsvU_zq4aD1lmnf;1$qNkn5HiMCtHd4PcfqL2y> zHxHROju<0lczVDPPL?5@EJ;puN+}u5q$STG5#nhk6d42trHW;^BvWEGa}wn&t`crU zYevtdWGHPr2<}^&5h_Yj?unU3jG|7JZ3ozg2Xm%VloSv|P1hpafA zd76}W!c<6UIQ65YsLq1on;z0*nsSWNszlB6CG8se5%4zlO0jBct~W54LnQ~7ao9lE z`N2X_Ba))j5Sg13Bm-IRg$6LA6;{d=k3GlE^OQl=hBK9jOsejBTJ$t=YfvU?qy#>v z2nZPhiu750gYF3iFA|logC~H54U`l+<%S5tk%Y|1v1fO)BR+iCc7EQvZNTOvspM5d zMkGbrQHMKBe9*pz=K(7PWsC$z%04U$C18Vw*Sz(Q)*%EU8mXJsG6$5h?6<=Z4%7G#(F(2Me+!!Q5g>tFt6-Jkcj z*T*;S-@bbTEzz@xdW<*@rrE-6k8R(|UAzC}uGaGiJ61n#S68W#X~T@4N9_A5+Qz=6 zTX`{|a+Bs`lhH?7nJdh+%I(cpPw$U4^_Tgy64V}_wx_Gh zmF}Ehtizwa_|12}`SXAM+i$O2=x!;k_*{!(5BB2oy6)uc#{1Qdj?o`U>Ov5%skMh8 zvv9DKg-Ah6Bd4R%hWj+u|Xi%u1KlO zM;EftOB#Gbf4|nkqSNy7R15Rz%-v<0CkG2mrs&4~=H-;zm9{JtK_RB1o~_CZ-X0xu zU@m-QtHI(RsM8o6I}rz;^!5g-GJ>XsGYU&&MYPO7cX5)VvlFAhLIUg&R8f^&DH6Vr zB8Q|oS&vBYiICGI>37NlOmOpkK-CLF4o1yAgI5W#6mWr0yfeUrq@$uRlM*|^A|{NT zR6rt07*nJrGOQS>s)WVlV?S&)dHBcv^XjvG4|jXs z_NP^$31FCkfj})ayHRRJ0~u*+XpRJ-@Iv4y%hIh2lK2v*_ewgY^gGabJ0-A;gA^p$TrW$jm9<%?t@8#Y219H zxciv;4Ki7n##QD8$H5x3?`)s~ry03P=d||}C*+|ZFG4bbRzgdFGKB%wAP#_SB@8MQ z4&;gvScrL22KgFXbnAIhg9}j@QI4!9vDIaY*jetf@BaFgJg%%72}z=2i3C@RB-(*U z6j*0igk`qe!^3f^$&xxDR*XU#2>~pjkYp#e$eM@->410)b_X{|2di@K!rUe1|>x*;K`HH6-kx=oKZ4^@&sCQ5GBKgrBV-%-fvS} zzx5--)yBa{s#&>=ooCo!=4g4WWiHMX-24dHpUT477G$cJhkB&<4TTNRf^8>I^kc9J zgd$X$lEZ~ql}$pN(}PRoNaC!TPpjwEM*)goZN$}&=vqKS=`a8+!o0W*Z6y+|P9f<4 z2wW1`HO@jwBBHD30^iu#(?DmGoBPV8%!R=iHX1P@JEOa;HeSh0MJP&c1HMw~>E zdnJynO(LRH-cY6)W=RL(oY}dLOrer2C$mm|gwE)S3=m71`Wlw(@7MkTh082@*ikFb zRTXW`y+8GRpeR5KO(aQ0-Tiub^>Tan+%#qcA7QM^!?xe zC+ClTuswYN?cDYL^Sg5Tr|Z+Vp;=V+r)MdN+&Mr+c|*wG&Ny_8(vFK7U#N zESdLiQ~9KM&r=A1$6woA`0tLUxO?cMv4G)h?>8bOqW zFq(zWQwC(_2%$h~laV6}ajdCfSbUYR)EwFk5UL>M3w7B364Sx`t3fvf6R zb1AeNc%lPVDhF6Q#zN{*8mA>QLy2m}GqUpg_ugjqEkzxNj4DiK2LsveMiP%JWO4Rl zO3?x37P)&)0((v&?hbdV93@GDDgl;t3KT-eC?uII2_rgy3hit}G9!f&2uVRExG)@< zKmwF0Gr`goNRT4-)H7vAQaV8ewfDw_P*Z6 zO6%H3S8g&nx@MW@Yf0%muia|NRu?~_)Pgk^lu~JQ5ihMkQY2Dld%lLu`-l-eX^vRg zVMyV|X*9EzMG=xQAXF2hOCj^hw)F^X;OeO|hHrb?=yG0KJ2A*X4v^Uj=Jj?<%KdnU z4756Y%P}O%;ZJF!qGJdWBP^Y{Hga|qniuF~hzLlnn(oYOGK3wP6fq*0(JC#4GJCf2;R%h$c-QeZoo?3= zq|T+KbPrpNhB(3dG1nz6wV@l1qH&DODQ-g@n&85vzTUWNILcDT_5!@j z7W=J477UE66pe^{P$o4YaUNZf9!1cUQ>BqPeb~q2BR5bYA}F9dGR+5%C^Cc;KqV>J zKq5q&!qOAwJ~-nsoQ>|83o!>zM2snEN{$F8qD-GC24#{PlSb?*B_Vtr85V5W8q+|I zz-;A0*~MJ~$?5UrB5-%kOhlx+xje9?nRyaOz>4E2K2rpkrR3lp1~jK=#Hq#hq1RI@1gPT|N%R$?J`LP93u zks-(`AoyU1hk>1-z>$Q6frP=W?028M{@Ke}d^ZH;3i%zK<|b!JkHMQT1d4braY$0% z!(6C%%A94^vGPC>uGBmWv1XA{nr`=fKhbV3hTka z*$_x*1c3+yranlJ1V$DCH_9Mvo)$yK-tBhFUE|PX4yq}U36U(t>#!+0Ed+Af_GokU zCpV@nzVFhcOsq;mp?-vq&caY4t4&9YoYaO@OO0KVC`<>0I8;J3SO!UqY3pN*NJMaA zr`S6Am1?+p+_rf4EI%pVPZFqbEZw)ps)T8}%rEYy9P_82w{sySl?eqzN|n+P4kTqi z{9yBStZN+h^wo#)G3Q(RmK147cDuV&9HudwJdZusBS^4p8SRifJEP--cU;??bY9 z7(sz7Q~-80NeTyo&!n&%HqTseI?debbh)c~ zrt#FyGaS}Oy;nM)+-}#eul-uab+i8d{Q8yHWqST(A9+lK zaXWfM*1``D?dL!L>Db?W^~L+=(O$hSoalYt0z~E9>itK}uJ(Sl(^8G0(nM*qES07T z8g+Q!IHs9vF+|z+@V+u}C3u96p-JbeH7QHXQ#rNiaxQ1dR)~ej!^$Ow5rL3k_F6L$ zK=S_eTX{Z?y<;eU`tiI7=jf$8ywW~|F2ua3KuHQ)QVn3nq`U?5h&(}>mL77?xzjL6 zBL->BNVO3$BX&ZgsnF=osaZG~<0(i}Cb6Co1j@S5`b>xj2P=^1x3mI=BZ+2VQ<`!- zlM@iENogpjG$ZjWEh&*E#~`lI#(4xJQm7y~NGGpM6roIm05FsE zPWQ(ze)SiB{|$kXnM2aY_ZRuuk6xr|v970SY=ft}UX@6~&=^TG^)0d(RW#5DsfSx| zc#nm(({7$4LFhXvN4sywhtwkZY}r^ks4=@zI)O7&jAMdbi2$g_MlmrR0SRO#0hyGA z3DVel=;UaG8|Ie{`*f<)!;5wy(UTUBGD$e6Wg6S+9_&G$j5YKEcH$FgFfT#`I3tr( za8UHb@P6c2{W{{h?r+xPN%|PK4LCfBC@cYFc1tW|ehTSIs+BUCgyE!;(N42+bO%}z zJE>3(Cn$F1P zJ%Fy|j@>-=dh2>_fgv;@4`Rx$1Oisq2I=TPQm$Lz2vY)~a>U?6<2Z&{T7`4;aQ)cv zhHB;VaUUY{i;o`kx_^5!5-t7R&C8mu$rQWuLM6z`G|^Db!91uFltc>ASo<2+hnJr} z##@f^`myhesHoK5%=f`;8|4@*>d2BD;R2|XoOEB`(bh}Cas=_{DU#E}%jNmQ zuw%Eqzw^iS-LW_U>${!rmf2<|Ek(=BIh7$VeB0!F55IEOhPHombG!|) z!K1p!WuXIp))qCj8(kJWub3@j4nU6{6r@d@p_Ipx<#oD~udWzQb<#HC`5bWfdf1m<(z zcH&M-G1zJgQsFgXCiX;v2B@KUIbbEymFWly#|Ba)MQUMkIiL%&6IybB8?eE;(ITv= zmM9GNh2ieXGMLERDMcxmU?3*S41h{vM6V=H@PuJ-QZh*qok}I%=QBR~;rB1~ zFP^*^B0wkPdEu$ZU~aXdaUUb(PO^w z)0*Xsc+@`9iEtyi^Ac?cm6fdCj2Q??Pw|ng$U)9U$e{(jWmt?8S93Q>3tBQ9FqqUB zr4W~k^hceb3lTS{CNswlUWNtdnt_PqAW#nxVs%O(gD?TfP98*(xu-L{BP(ELtM7Gx zes+_w-NqIfC0ooE2RSLz+6!0gQDW0UOnbLEDVbcRl1bB8#~3^nwQg9PtOhC8{gAL8 z9_gICrPd4{VO(b^1m8kR90>&i?9rcZt|PPaB(x64n$x1|MwuPW;wnF{-)EL28abMt z5uN3v1gT~D=>G2hRH)Qxf$~xr6imT7A{NJnZUEVce!Wtb<9T~}x8^?FtW0fgO55x$G++L!S}w8 zXj0_N^Q#99eD}?xTu!yl!?&aF!pUb2+=X}ReVSV1iHN3|dAfi8=G*mYesw8sW^do3-sK$Yhe1u?v0Ro| z$F@I()ARPl&Qd@9Oit(i{O;`+@AUrV-RGCr({ca0+%H8R9`5fx`oTxv|Kacdw7vWC zi*La+ooD{|#Y=G9u6CoKB(|Ix-`zq~&xK(=-IwKIxoEv!*BXAX(mIehy|`qz5i6Wv zK`LV%k|dJ%^VEvtpwgsDIZK|Jw>FU!r68%vLhFt1E_7&yHDNb%UJl=X`^#;Q_7s?x z^6GAxrfAyciJJKRM3r13(kvSj5vXunQ-wp2oe0tHgAZO_72i_`Wd?{DbUa19%kiwo zf#wj6GH2hB8}^i15eLG=HL|mCW)cB$gjS}2LP$~yVi%;7aI8!d+wKBQ5GAZfDeOep z$b;%6I8p?%P#o-rFe6Cc5|#HO#3&||BVdM!(PL9MK{nJviX@OEXOBY6JA$$#5o184 z5Rc>ni6o(PCZ;To6wV}JNl*cVsV9&CadHwUiG_qI8D@z>2&AzJ1tlV4yY>0&zxlVuMyf$m6wN(_@~J7`Wf(Nczq^5~sv z*z^&O4=DFz-&B&wIMp&#(kTiL$ii}UTO7TlN7XdXgM3(OhPqOf(ep5&Yf@th4pWcD zUfMV>m+8Khhlw;%n5ZO-i(v?PA`=k^A}SPyl1vb0Fe5dC0-f9lls;l?7@KW!e0URY z`~JA@Pc$}lMzbizLtq;x=^&unx*y!ovhJRth079s1Q2OuYN-_jOA95JGi~e5DMvVn ztOHWO5T~h9ktNfCutE$j)wTHTI#QA|iAXQjJxQG@oFNm2p^|zse#b13hd-aQLN_O9 zdnNlmp5DE9{S!n-sE?66mqa)d9~39Z2(pa9?G(19@6>n5q&^~s?av!(`S?7%4}P)a zjd0?gP~v(f+=%9^4KNC1TH@rSUN-Jze1VBnL5(aUkCwF3TxfOXZg4%eh*+;3^GT)O zef03r_vB9IcgZx0>@{VOUg<03Lid)^F;-w&Zc6l^@eD0nzT&8$gANKKnY7hDT z>6_M>@`t)Fs~~+wb0fyFXsF^~-NA_n-gdq5RW&h=s*B_cV37lfzI z#GE6Mfl6^G;vi@SAtH%8r`Cza$|xfy6_bR!=p@LXG%A{XFjb}oy+xTchSv)RoHix6 z1|Q<>RAV)2)CW&%GDieWg{(S-@CYsxJ#?eEupF{dS61Pih^9t1Pzoq>z`+!fNg2*0 z$si^t{vD8FBoqViW z^D;@ohtP7#eiMH~QrE7HgeWwcQS_*cgE^gwp|ihKc^5osE*Q@#?P#bGTYyG{neoKa zU{iowZmh~oNnLbKX{o^pPU287F)7T5u7MNL?pYW?5m_gS2y%fsgo3z=A4UYYrLAsb z^pe*vefPd~+tmQqY-2Yxa3Sj%Zj`|6W>UBZvnI(bc@-&se^?xHQ-~&jCgSa!DfoErpq(Z@mx`?ESG%rHz;szw*1NlkPotcc>Z(@=S zvn+d~nos(8?fvmQe~wdqdVcR)gcH-`wl@|YNY{XNzk?&5N+nbUzE@AJwi5<6c z+}am!|LV=#CpYEl%2mRJ+0(h?4v#8&KB3Bp6d&7!`F<(yNB6_6gnpP$cbas4dfZl% zBBMsX?u8WNnO>agJlnSF!6{1Jo9fY{e{+3#=MNu!^!~$BSHB!a_m_FOuk+>GuYdD+ z{qCYKv{n1=@gS|jV|!fUtYx`9emne=8MR=v`F?-*e%toT>(_O6naJ0{1V6kT<>~h8 zk3adNZ*%_ci(i;E)bjl1?c0}M{q&#wH*A-``B(oFpZ`iKefr{czgoocpZypA+5PM3 z7ysdze(#T$A8?}|*J}I}ZN96g@4tBUcGRhz&iUaREx$P3e{y-4a(rh!e))G_DU&jr z%RY>IMjJ_ODkD2}E$+dCL^8tXsg#IObRk(v<>ENqXX{0ndT?cUc&&^H73mdBWxWN} zlpaAbRW;>^%Snh)xGqz{v2wc$VnkAz!w2z2)CUEz5oS#?9CBQ}ea467oX{HLNVN!Y zi*}*)UDoPCY?EO3+YV(urX&weq?LrHyPXQaREa4K-b(IkPLgPBdk}~jJkljo8I!P_E6d`fkNE}jG*`shC;D$JeDso>oM8oO8GL_5QW&`gbWrz zW`-mu!ojn{H5_}PvIQ?}p5o-UNFfq1QH;z&nP8_7L}E8kW=@En6kIsW7%kbHxKN~L zf~bh{?fkm@{?9%>|J$#7mT>1RsVXXLN4EPh4$cS-qH++XFiG*F=jr31t!nJy2qsI^ z$YUX*GFOwc@OP@8?EM4Dnfpy?a3wyBV=>9}uG6Wc?XHMEP2y@fW=ZOHQ(f%X)cPR{ z`q2vZ<2{!blHDjK$;^^2G?%iz(ejZ@SqrfMtN{}YM4`wCCx1!`K_onw5YM0ssAf7K zi7V{HSvjAB2vT|1*x&Zsu*W`D#MZmD+K=5ri;#~{N`VkFMNS+>rIj3}qxY`GZjJV1 z(y3CYl;f!nkQQ>!?tX+-w988)Zp3WHwqO0~SAQQv zPIsq$y%C>Yo?d0;>0I6qB|0K*Dw-G4t1A`UdRt1lfBF9Xcjvov@B6kN9l}j_AAH@y zIj((OfX_eyrQRkMm5I z^T+%8{_&T;J%99Zd$`!?=kI>`ueOKJUwrz5^2@KT=(9zS#@pDgZ$5hchu87%*0;#y zH(!0F?&ZGz?A!nFSO50SZ{FzgKmLC&cXvPfvwtRwhFrKU)9mH`lgkgkr!P+9`UmIV z{z1g^c>K*bfA{?1-TUX~<9v6ypX=A}zMC!=PP0zY3pE~W=9cP3m+V_@Wu`cwx<|Qa zJ5{xDs&T?dK9wSgBo(m;CPu(0P8Z3Qb{|Fu1(juNU*)KxBCVj??#BdFyV3l>s3?YV zCvXRtCP#9vqt1LCC^hW~dLT5cTXy9JnP8#Eqv@=f7$YjfDk%|V5=aa>k&lon;~LSk z5UgXGD4o|EibyY^M`{U-970G$hs{(X5pK}jKn3W?nqeNy!$}g_K$E#=WYU^erEsFq zWZ+~wAX9Jy1x-DbV%?+^_)dqW4$;NJxr1`!s);Gb#&t>7ECa!TEvb?pil!`)fdFNs zB*_2)nTSM=%n}&T%9${Vs6+#v5cXtY2N7IAGR@QF$G`uA|KjV>StrqbdU$1IZ7Klln;7?p;NAhvQw2b}A(;e(7sEE5$mywyC&l_iwaU5Mb z9}{wLIw?=K1-H_-P7|}9fMa%}rqHml0w0sZ51WoRMYAGVDx|BJq%5+(li|BGW zP2nTCRB1#A5yIY+=YT}S*!O+q+q^=+dU;zCN6%Qwx!^&WZ`Y^EJR+J^yk<-XSk;q%`$@21nqC9{1-EZHn`-*oT zJ{+mDZEx2>6!XJL3g^BJbFQ+mn_fw_4KgRq3gHr5o5i6sC;L3T`mhb_Oa^u zq_Dm{lB4fqyFPokQ(l&(m|Xo?{j}OTEpmT3-M_p)cK_zrzr5~;mRRn8q!HKaRVKYW ze5^ndp6F8am|mQvOt*jh;)}oioB5O1%ZvNc@c0kEd3^uGX?LH!miZ;Ew5#`A|?|Ko?_ z!*BoQFTVWc7mvUFyVs{LU;SRorEXvT<@)BA^Nr*5@%6)MTJD;F_STH2(i<-!G7tIU-+tw=kSIG2#qteze&Ml>~1c2SQR;+*MPv-hvRIo|aC zysDn`;}?a&)BR}{YR>10+q9HM@G1Ji3Q%(Ht}i(|@^=`ek`z>>$RuG@QYOD4DNvJ@ z;|60sI`NbhY)9yl=;2930YEq-Aem7TFtcNh(C@ z;|jTCUYRV~iEA1Yse9a%3sTzEMWxPSg<3)tRIjt_5cg z6~AS4FU-c2&H-wrd!iMFM>Z+hg90^}+0zBuX7a)CtoL+%%IVIIYt*}tO4C+#K`%TN zA}+ZV7LwZLY_C3U7jUgy99)?q`GVLpoJS`tnUCNLkPM_UX_2Y2j|?R~(svlA?R-4< z4!idL_Hn$AW9$8funcn#h+_yRYgig03XvG5c3TgpL4-+5l`XX@1*fSL+crb99!DiU z+=kI%kpsqL&Sh#9)Kr-Wg~8CtGE!)4iESN9+L}cY@fZh$5mJ{BFX3Q6xZQE%(zs~a zEG^JIY}n@UbX%`JJpAe#$FbXRN@l;M6`1&OweuZMrSX+P#&=^}gQo@{cJeCyhT&wl z8eL*gM97gqTBfF$F-6*NR4#K4BvBOdvVj5_G=hJJT*e^wL?UifO3@|tAc5b{UhY=& z9pmcl*sbsD0YCbF^#kdsWgfzZ%3RK;lf^+cmiyV+QOZ6nr5&jzYL*_J$?ec!ij9bx?#>(k?A``zUfo}zYZen6*b8M#+( znN}v%dD@?z#{1`Sb*N@gJ6}fPa(@9aRSwBA%OaC)yQ)T&^loE6hJ1MUe%rqK?0bLw zYI!k<>ew!)yCO|bQ`#8o6U;V$dEH}wej5@!J@t;`{_S^9@4oznzSv&>g9a5{r!Kk@1l4%mJ6x(ZQOdk`SSg@Z??DB z4_`f(zxwyT{pk;q>J4BUk z8jKCd_wDmt?ybdq#PB^Rxva z>%OjY!g}X1n%VJq)DkLM$ub>WDidW$DpF}YCN-j>RkM_=34qk4HRgfnP)%Zlh;PUS zrK~5CHM6ouhEwkx8^=b(@S+-t#zd(}#M)-pDcmS%&>Wr?or8TtEpGh+~WxLVX2FMort0pqv>(#FCPd z5t&(?DMJzs(UYbD=VWF92XPgr90Mas7=RNcXF?c_vJwS?H4@N3Ne(#3k{yNn>8^e9 z>5Ggwa7?98-^G~uKzh2sw(TfRlAJO*1cZ_+XgYH?HV#y&u3DMEG%Ds1X1NgZj>+r9nX9}SLvc!Vn}}{$KBX0&*q`zx0EI3 znes+q;ZKog*oMB-U?2!aJdhDGMcyo?@D9r03TUF?7$A@w={=$(RwO%R96Pr6zDp+O zksMHFuQMlE6|1vtN0#Jt*rq*g@|S_)~VPtzdJ z7$beVJ|`jiwa9FHfB)@=>+=&bxK1eoh(#|izb~>-EFa!}Ma_Tsr~mxb{rAr2`PAn5 z#o5`3+xpF$>(f&?m&@xv(7gELb-a5&ee&YrCqG`!-}~ktzPkSAJ9j_ym&+Ythu0-a~F}Cl2avEP>ue)~nBPIP{kjW+b&Qa9{cOiErB@UO8KxF3lkezw#$)Ip74ynNw3GgDp zrh|yARI4?^VmE3+ty6Hy5hXc$I$+Kq1Ts1ptd(eG8YzQfPqwrpaUfibD37EgO)`wZ zNsLS=Aq+~%97Kth6!;wjM@G*XESNa5^4F^MBG71j7m zj*&`H6NewcOzvsZMS^$N<7P2NQSVBel)hC?I_wmyplI}R`wp_?=xoKGzs2E61O!aU zZ!tQ%a}EkBk&?zZm@^1O9jHi$BjJLCr^mpE%QYk^=*~8QZLCAuK`TI52oe-R^0T$8PRH$fd(9(EholKjg_%ZSz z;RzUgK1*dcm&&FsoH#@GwF%Sxg>a*D;Yz3kN2a;hjoE9d)HkVh+4g_5>k%L%i?IlTj+Ew;Mm~pBa0-Ha zh1Zm1nSh;r2MuC4rSL{RBTUV41OhP*?0c0{uT#rx$c4C2ZAs^Onz^x&vrg?iPgC#D z;X|YyHvEV-sd^E#QJWoi8WnLd+`DZ9fDVZ7MQqX_xadZtsMr z?md(0GIi&^uHXIYKRsMN|Mbi0S8x9E;qzCY{oWr_k{3@;N#`gD5R3yXSBJ;XiH9->V)z_ceBSWEhZJt^7yN-Dn(YmemMT)zx(Dl zfBtt9|MGHLn>|Y*4!vEs+{^-d??x(>MR~b9%_uR3EVZ?knN?@G*&T-{F)31&YiSyk zT@=I)86gC+!Tr#qAA|I^b~03z#;DwYVxm+UWO60;o=F6kJaB-hQVFiXv85>X4F?Bj zX_;~-ga8qUT#}F!JPD&x-f~aq+C5=!lJ|j{F*{qOVUd+4F2c6uav>dz?m`^TY)0uR z9z3{^AC}=5PeRR^IVNTT2FCzVnr9|k^4`Ij#$bdRQz1x*1QU{g2ax5qQ;Jm<1U&q( z2nZ#C@jKaEj~tdvP6Mt9p*Dq33cyN|oDpteh!_Z>DozJ;I7<4S=?DiCOOiT92NXzx zayY@#$%#-3m=Ios&OiRaLt%kmnxL`Yp3yj{q!iZzRI0;y3$+rCVkXGz%$ zNk>K-?>Z95PSc%m@~{J0it!*SjWfA%C?D)BCBT&q5l%V*$<>Tn-QGA=CZ9^|v1H6; zA83=x#7$D}##C8^{F!v7HbJWGAFL0v%;9c(+6U@8BEg5#2+5!T9CU&oir`G5gJOV$ zVXw$;F*&s($4;k% zWL?eEkRYL)4AWGEWs=H6%B0;gCOdX`9wc4LNIz%~6h4OPgl@5yS=3QuDsgIkY%~t= zBEhUxwW^Tn+@#i4&n+bgF|5o&CB|0c@Z!|>5vy@M^=IrOV_@U?kr>O8Q8;Ng7Z+cNB8%DN0ghaJo^7kt8O*-4H~)5EE)4YC;u} zIbEVGQc`BkJqX9CG#cGX*?GtaU5aP#eJ_fUN~uZET1jL~)i8pR!LhC5w!0^i&0K3c z&GqH|{oRG8LhjXi^kcNvl3|K#dyLiqW|<#&qUqz8W^dLHZ#^u>SIJ7}iRjh-c-(&d>$h+I zPR_#GuJ7&o+c(m9IxVM9mLL7;pS0=hJ>&g;^yBV(uL?=Zm?m8xkMC}y5Mg^;rg3-Q z7MMM4{qe&<=EDL-lQH`dYnT0)Ckh&_@lMab`YyisAO6#u@7_c`P2@*T1L0agb=;hW z=h1T?ErNJs1~*o5Ntz_5xrj5D7TJ?SS`**Pv2!Nslxb4JWH_Yze!ZFXanz~`5_fP> zG7Vy>M8yvr2CC^(FnZ1?B(0*JLCFYOF4RqM|*USRhBQ`7nER^BoI3mYRt*~0SlWL~Y zdd;M06?-S~dMIonOEx4e49{TXnwb!xame)+Ay6hIFsE}414d$CV>tQP7zSZ+$_^P@ zMqv=a!;^u?J;KtD%tUH97(F0>vvX#N?7kDY0!+%l0NA5~0^x{AH>RmHyL|ukpL}wm zBxbR6ViKK6H_lqB5{=YE7L@zJGIENs*l^*S7FE5P7{Wy*+QZuu(LcKQd(b=ueiZrax=H%<1 z2l={=^%)k!GY-#fqn>Pm=#=j9f^$u-$qiCK4NT#yQH#j%1RTDj-;yJ3*v?1P5ealI zcWgmq*>R=F9#rl-=T;;#Gd#{qOl61@5$q-;b>e*;&ri3*!#&6CmgYG?f%&q?G&3g?<8J9I|v?57(Q&wr~9BJA+D66A}Nri);68c_gKd^Mrp*oQCQe|!DnfBwsF{_$_OcWe9jp5~XR$mR##51W7c@BjSGmw)TAgFmw8mD`E& z_~Pe(@YA3FtP#c3)^BbY2T6cu%;kCYT_@+5mL|?~9+@(D+_vYw?vo&nLCMFlF{Hj& z8lzvG_HlgsA%nko7r*_ApFX@VkzEGPbIS1JDU?V>h~}D{qn#dVYiF2b(6FL9seyWq zB(MZ$gpEunPwcj#o-n%J+}3W}?p;Us9$Zy1#jFw8OT9a@FJe-Z3Z->YA~WKdSi?6F z#cj|ruzyIXqa+JBSrWyPOR7_4Drd?YZ$ao(Cd}t3HFX(VW=>42l?i?%F$H2ڵ zTtp>IVq~I7bPy%vLJa#D; zKi-oroSh^|r4`MT%!vp-g1ETVCjB~uuESW8SfrwlQG|_BD7uQANmNHrT%eIm#6b&D zlNw>P6IfJ+5du+GnJ}Q-xW-g*|_LtefqVuir%9y>HZ?hed3l z9EJk9g|Lt@6J;WMMiW+oM+5<(OZM*FbA6&CM41?FodUG2_?_UX=82%g!k7xM8zHAA zx$kmys*A9*N{a1%WcV=J-@boZje_}V-I!!_8@u~DZtKx+zL~>EqnI;Vsh2X&=gU$c=ZSe@9#jQ#k2pxqQaX?z0VyaH zC4(s3WTIivLSf0oyGPNC)$O1oaOB=yPUmu3{(lVN*|RNMmLF*SMl+O;O6PwR7_BssKI$7{sA`OgK*DfU!qAW87fNoJrrrLX2=GJfI z(r<0O)&w1;GZF0(=;?TuQn}jTn7Po~pPgTS`*r)Y{rLX7T#ozoWxhY$z5a@u-#&b> zTmSt0m+6Z)Z~pdY$say^_ovJ4aXNl;JpAU<``_#F{Kap6m1P$?x{Wbbw(<1-TB?|5471Ztc3pt(&m)*zf-4tCI}-^pcn3 zZHrco9-nSzZ|?Fm&+BT3gP^w7U@C3O!p#jPYM`{_wqK)X?mL~&*fu>**!uB8`ax+g7LGxs3g1d}em;hMg5a*%c9h!tKC`bd6 z*@v0&=)|sius(A=1^M^LyG*v68aY9=vN4faIQos+Sc zu_h108iND^&T!|f9Z5({ONuJdi6&xmV{%h9VxcusT18lTEkM92oTG&c4I|s703&;U zt|O?k#polLH^_+y(22Q+6pkL~VW4q^HAanI&HDIM`>l=Vwwv@ejFiR*?*Z{7*n9PC zHiE3zYI}DDjHnIaa7mG)fWoXdt39^e*FAi1F)dj`kB4a@O-d91C@_FAUP9rcTTXu4 zI=CCONSKGaQ1ZG5CsJ#>$TE8b2}Kecqt}qXn}0!~G$_X4NmvDz)L+t4rYQ46lsBiW zb2$~FJkKtfSf^p|un38BXSSAuXUO+p9U9UN0r*G&$$QCB!5N zVrCXWB%*LMaT({S&xTPCa%2(N76!Ik+HAqehrLm#CUajRbO5lmd}Ub`;gRbD{+eb zrseqd>wop>+Paazkd5Gg?)Pe9qF;vEuRiipQocrx$C#* z_m7X;&U<|N;$Qp^)AD*QuhXk<&VTpcoxb_PTR(sGYc4PS@tV$yF0)^^{qcL|J2*ez zZu|2sdQIhxwJRyjuU^UCGFs$9U4H!2cazHNySJM4db=@-MP2$hNg6DBj4rb#Z;=5y zPKri1Yxl=|sX=BAY6Hq1=2qFUb2;uSFzniFDH^?V^rEROHm5YtDv9Kfgi?-vH!Z_< zpQfY;8ooTJZIpAEgGR`Sq6>A9uKoJ?aeaT`533oc`&V+#JRK%UMDyV&lqjmXrO|?dm<2%$h6lNqLm{W=p_#T%p0kQN^Jo-m6slpASjNStv(#?RjGH5o zAxd#4_-3Lsr@)om$&Ku01}Z8HM1T>t!V8qcf<&1Jh;XMt5CI9JyECUm;sgnDHYQ2n zPGS-qNm&pKHe!+RAPf!$8}UGBSbz`#7KinKK@`I9M#0wdPyg`GZ-ifeJxz1LQW(4E za5~f)cHKNhq%#eeg<^IcThmkqs|Jf9g@&Xhf`SX%7^%$3qYydVSZH*BHI43SW{D_d zJ4>SwFnj50qSa1E~)-Kd;W-Hk(T%>jL0amf_(Z?W?VKI7z z+SPfUhD8W49khUu!71wQJvHcnGbKltl2SrpQprpv(NWPKM>kt9SMW5~J}-1EQ!aFxu$(6il1wQ@naWTV93hn{APfVD zm2)ISZAJ-zOK1dT0Sm3&DPSsS9tp^PyLii(&$)yV)tB}CyO;0Zy@bm*-+qxjzw{ea zOOmJO6_|E(N-4~>%#l*jk?YWrrkP*8KE8f+I=wo#{rS_6-+z4nVXsz)ceZHU0>si` zhr=l=bSXJ9Vgoe4xx@AHd}*O+Skz!>o&5E<|(=@sR;Y=^}~F+Z!b^po<0p6)|cwrU*7&V zzdrrym&@OLef;vlpZ-%=e)#pj8bAE-{qO(r?&tq%Y#(C8q<5Sqo$~diir%l=^WD#W zS>|t_e)#Qle^=%=&)a%;`uS;j`|;zSe)gOH=G*_x|KaslzkK(P|FpH1r^Bn|7_m;A zYl{|~^L#a8!Rxzh&8ToDj2kuPwmB#=CDLTEYsz89-s_0bdgAJ&%9IMF>9|Z-l4~Ze zBc~{dmRT91;G9#21(>8zR3>5!t-C437_FLxetz12+UTj#vP`dLpO%zaf@7M}y>iZT z_BDcn7bvuKpAPJe0vyU?!;F<=G%+eAYllTIjJ~#06_;9i2&G~Q;-G;5lh&hNi@ zbI>F(rwAr^BpZzEty0W^LZea1BqOv)7p5MeL{7};j6%UAY%wUvSrZUpLWGE*lzCKU z4HKjeR_X^LgD4_}dBDUdGCK(oF%(2X?kt1=IU|BHkpzM~oQSCpeu&@x7a8^Lj!G_^ zGAZf^BE9ssZ3uQW#;8mc!4#x$?}8L!6X6LlMTC}t*7MXwxp$~#0~>jd6wJgV)(2%x zg8~CXVqqOF$&C{G5O`;mfo^^8JQD(0NJk@5p(s>^M9EPSyfT6`vxN2C`vJaZe`M7IV{LJfVmLpZ0g z-b`rtyt!Mj^6;ctCr<49fN#~)POu=`t&xw;x|E^^J(Nj1jiQ<7Txn)$Zg=o~OdEa-7fSDMu=bK+f>PBwivl zNP(|B77TFW2u81-Ckk-95S@Y@R+t}6-;mux23)Zr#%%+sF0uPrn7n{`~3o`Ezeu z;t6?M?jPp6SH2Z&&!=DiT59!ln$Oez>D|x%cmMl`zxx(({q6tbf7&^Y%CzqUA_^1u z(5+W?PZJ&Bm&?GS)T!FqJt{^zF6^y0qey^_FcsaKr;@3I7&D4mpEE64mpL(HcI08x zG0(_4Q!YeioD!3x%oIlCLfS1@C``@Ty4O!Py#KhqbbpxWc-G_LputlbjOniUlu7B} zY<$Qv2wIRr27(ZpEG62FdPuLJaAvVCxsc2pMtk=(i5qiR+|mBbjL37;VcZeLlo3q6 zJ0HQ#(t_5!DB<2>q!zA%;Sm8z0s}+G3eUs}bNDVa+q7`s2v<%^ScM7f0*JU9DeaYJ zW#2=Y5lk_{Sj9$T*5E9%yA)2KuC5yjQ#hnVP(XmL5C}O5Ig=`2p$mBfIq4+5I{^e& zp$?+XDKUElzyN|&i8Dml9Uw?%?*KEg(clOWF*y?lImn49d<#$Qr@g&=yqh?k3NMF1 z)X2@-x=Fjegp0z5VR)dfQnzZ#UR4XMg-4Jp9V~X@6O%Yscy{kQ&5O8UOwNXpD410| zg?FOGcn5R1nD2(91o29|Sdb7!niF+c%tbvnx$}#)KfZ!gGV>!p2}#>-AvFs zA|qfi#L0N_pCh98ZC`KMd9-F>6tj32!Qt*O z-=B2CGMAW=gg}US1qnpNcVqN1YK3`k)%UHB$ES{%si&N$;q#%-b6V~a3-pjR8R#|X zMkL@{_7bT84KzkD`4qAe5o(U|%*fIQiMt1n-AC@-F;cYa=;3t7+-a83Zwdd8ya}A?u zcJCa45#~)qCB#!b&Bv+C+o#W!^?3Ih+qQRrYIw=qm?xcWUS3OGlj>Xw9Wq*VVB0nd z9<>WI)oq}&&PCI8y|m8Og=0K?^KgIn^)$^d-~aQrdh2^|u&w4GB$7SdA5ULDB=dR+ zYmZ>rp4R&Qx9j^qY#+Y+@cTa=&)>2<-acK72U0nlmX|+&+_#r@?d$WWm%W!nx2Ko+ z_1op-au{N=x}4^Lt*^Q+fy|F{1#DgEyM@_+vR`)7q8?~bSy@T95MeZLJ8 zse4_BCPfpnwYJ-Uxna0!>0LQB8>Hl0tJO&&rd&FWy%lAlIHi)vC(V-$nM#@Bm=Cii z(O%Mlf-z-@5D#YvG578W@oA`;=i1xn%lL7lPcQq}>itpgCpk!n()sZ4km?LgGD3@j zC5n6bhmI}`B|s91=TdVt)C!AbygFo%E@2;vMGA{pVq8Nuux zP$mx|1}Fq%6o3GHi`l+;+vd&tDYWCXNWg{RYtGABPF~YlJ7$+U05?ZevBNyMRiE;`Y zj#9U*irN5*lt$f0t<5+b%{=B(!V+nj4pJiJIow#h+cCy%bhlcYd)c2}*1FbB1e84HLdRuZmU2uXCG+V_=6ZM?(MSwJ;5R|f zj5InEGtp|C$;nw+3!6g@JT_wCs2D=wz~+{QbGtU7nU{gPrG4H$y!eO5PkOkY=b|Kk z`u>xi57u4N!F>d!GR*f{RWm z&t)pd7+3F}Pp_6)YpetfmL|NE%#(EIlA>BA%|YX~TWX#)d$<#8LQ*|W%kXx5_`>(6O9P0Ky?8(D0ZkFQ?+?Pb3>^?jrI z(m((1r{|Z;h`PUAnHHTi=Tg3W)i3Mqa^1Hl-pk9n6+wkdl)C;X^K!cXX1sg%`qy8} zbkFm$eDh}d;&lD)_y6(#`tP2$z0C8$YEAR;Ksw@P+1Ofl&UiZmlB&rbHOXu$&AKKD z$KLCFI*ym>6Ce{r(JT9qS=lKaA}Qts0ZW$oAg8c$m{em<;Vg+ltuX`&nbe%&9*iD{ zP%zfopFg~Oxa^og=>Z}q(Vqu-q zOw*u9#A|Sn&hRc|!AhgKEQ!DorU^m}Kr53*A0EU)1PuaHCz0SxkWg??sCWpm1H|6L zh=^kXxnh`5b18`6VNeIDYPBfaUw+7bD{qdjZW`Cy(>9jtPZu(4(StN3x0lZilegVn z&6@SfNa6ijF9{s(#0U7QU^io7gi=6K8KVtAg@e=Zf$AJVLdnG7nTENi*f|#nf_bzq zGK|lQfAW-(&RKVLl4aJhDGQZ3&{!F5?LL8ZL`bbR26STWe14P8DV@%_2sm*$L4@20 z8z8Vi2l^QMb+olTS^qHlmiCwKmO~;^G7!0s9dWCk5c6#A6yz3U@X=B#Q3TcoB)n}^ zYTF^l)~l1G!Z{-&%4ud+ZI|H@g4iR%yTe5XiNTBl*1M6+hcP}Q7jiN|45tvo#)Vu8 zm~0=_ZLHQuFi1h_efZe1R@-jN`5vNv8v`-i_VwmYlt4oT>cgAsdL{2 z{Y9pP4&PQn5UQ&4z9+8)lMueWu!OZw>?4F}%t4P~#jHcUqXvn%K}W)c{OIW7x2~^g z&=|8#1qkp$F)5s*)-n8vNj(;bXy1D&&LA$DMWb&Er?Ed1Y%a;$^OR@Sx?P^1K79D; zhaa9kzQ29C>=)b5oQ)-G0my8iJW{@+b?gY2JvIR0`v{%St{=IwU*;k$qT zAD$j>OIeP|B|J$4*h?PXdO3K)Jf)PhuQ#YIuihF(kh&Chq&yKN|FnCiF)Zg?N1M&O z^=#~Mn}%eTWzuOTim*#%O^ZSUeZU&WU-fVm54SGbJ7U0)xCyG+81?o{`g9?$d%2%- zo|(&7EidVSzJOE)nah-tFh?gA>K3^q1zZ|U+@y!fy22bm974S!44J)%rF-T8S@a3C zNPD3n%%ZlFEg&vwCf!-hQ)V}D$i9obBAyiiftSKuc$l|NMqa~R!iIAmE}`AD7-ptG z%Iu+~8%<;!(IRrNkX;dQDXtR>K@!H*k%J-_5rB6L4~HW|dJs_$0-)raDZ)ve z;gOhvbS~%l;b%X0VjhDf@ol$j*z@Oo-}beSokv~At<|;0rS)yA)%Mk{b*zRPip8N1 z8>ajIwAXnZ$~}98*lvSq?Cz3TG>ID#CeD+j96P%ZiL@Tf;vu7s2r7h(!hKBCXqoeL zR;r$l!WBZ{9Qwj`0g_k;D`iM96Ss19rOchxORH z_hq;Z+eo3d^4`om%!7oK`RU=h+hUOafKgEVZIgETtDS_Q$!iEmr6Ia!E?074d4`w%jbfInYI8oQXSy}v@~-wgQSRk>e6~0n*)6`-rv95 zui@?ztkmZ+-!F2Q=Q0^fPI(|f`4EyQR!)g*I0|%S5Ni_K9mM1u9v;L20ht4XwZyg} z&+d@8j?UO`b(7$p?`3}}Km6(A_aC1piNpQf`#*ozH5lC2-Yo*)EN#TB)b^UoRJSpl znp&s*0!|nE*K%CJ&zo73fAq<@pZX?{UA3k5#O2ilQiZFuP>i|^qd~voZYu>SYP_(@_2oIS8vZk z`@^q(l^>4JKfbGY1K)&Xj>*KrgxA({XIQsLufA{x)|9|`Y z%d;ieY?a8h(?RX|vYXR7HtA!LcsS)tk1>c_kJ0wJiwelJjes>9-YpzvJ;^fVV5gLg zOuVTO|s2RwquMr_atMvQ8aSUmWMF#<%`xiNw{A)KI0 zlEqg_FquRuoDt3C46Bkf+~5tAXw-IGQr{tqw;ts{x_O*|3we+slx=iL6O9ot;0{_N z6oW~FmtSzueT;pL-gk7=xBcb1AUnzgE7cBhRl>nqP~MB&PfT--(3!1_Pmb@4fAI-TTu^f3p63 z+iqhtfO4P{B_A*!y*5~>wU2NfV-J>0Ds7$@ksRYdo$i>Kaw0<|Mg#;dG_I}7w%uC4j$z~4m>~*L zw>^~udye7JdW;SnikNm+nxKwB;(@q^Bws_Ra3|e780=t(g99NYv1*wqR1C$#)(VS3 z-B@_w=q4VG#}>$j5mZ>*9iU7>!73;OM@(cUp4^qtVeZjEDr+lo!x$7R=@RYMjOw$j zlD$S|CoN;dK02Ol5v9_R$;8`M*?Yb2%G@tE?+kR?Y7$kULd1yXus()W%PMzAW}-!h zauF=ka(Dk~-!C#9rsC^Xo9XS!8x6k=nnLp;ty2g|q`d?%7zh-;lD)!FzYggju&Eq4H_Gfgzpqdys;3*s?m`JGE7OV z8_4PnnUD@)MaIo#A^}bd!}+h=;Vl6|H+FaPpv3#e&Uikw&FU>B}U)Y?Xq@^^)c8Z4s~m7yV&mG zIePC+;8lB%-J(7F$Sg6i3410SfkCk|_3-W%=+(!~jC${5ld%z6cyD{;-87nwx>e-8 zMMdj_T28bOFqFtg@BLyigOA&W3L~AzbRKj(JRh>2s5pXZ+sK=B^tyZf=o?!b zwKm&t9*qMr8kLf~3RDr!8KH!_E#R|d0&$cd#- zB|n_z(TXaiEn2vJf{bb$l~dJPN&M{6EUV%p8UH%I2g5&G`a z{(O6xkH=|VUS6L4Fip$pdby2xk~U;I^wHD8;YtLgJ|lINbS~C??2TDrYP5$C2D=YN zjLi^jx;x$7o!86f?fG`NdstN3*4OSkwX~cQDS^tIzWU~b!A4u(t#jBuYFmY(w-ynt z-uAl1=AkJj76|!lK8OaifAP)VV%W#u|KV0^o-?~Zz|KU>s%cKg!)ZFb4fG!C@vFCm z?%%)v^WHzc`r;Spez|_)kQ(c{j(mdZt0A5DJ{?*)9=yK#_~Rc|cG|&n|N3XYDfjyN z?XMDV_1b#l>(lpd{?)&{z3Y$v^xMbhYlfbfjn<^)?kpX}_i+j5l*0QVx((ji0N~8t zdW4`GWJeDh4$UqphciS|&*pr{Wl2Qobm9^*k*2IA)0sRos}M9%5(F#3%~2*3b}XKfJF$Ze(a#>D67C!c!RsPWN|rC7Ch@7r~&I8AcLlAfaqd!9k$;0eyv0 zq{41ggp!0a8zCh`5c9wy`y<%_=mriK;$#Z;925v;R%n7nj2b)(GfEGC6pG-Dp-KH%v4tsS(f2!X+XIQ+Ej& z9?JovkrAat1RsM#T$o4W(I}TFnnFlG;^7=jqM3Y$gDp5qj1UA9gAv4RZWu}Cz<^|y z3EU%MAe0a!5e{g8DO#WqiN_F80tf^NBJ7yr{g2zr^V<0Ge!V=keboIK11pHq7;-pn z&!0zaAp($DjMkO`39>e7hk7UTuVr&5~+O z<1`5YT);cK!dp0@T}SKQM|-*9$6l|at=0n6qalyBNAJVDI`7-Kv=%J4z2;#sNJ&Ca z38>umajmu5V2|y#qwnHbCl;O4aZ2-%Qlc2cJ&3(AdIiCSJ*l;5W1SeD=fuo{T!@!D zr2x6t4RG?|y?DR2VOwjlyN|&_w+-?y^WPXK#LX;82{2P~+X^pIcv3&yKPbB_nzCv> zB2ZSY%7>#f! zH?Ll8psgKZq+AxIJ|c9qTHDyy-Pr^#vW#xg-4f?AN6sU{b~k{#Q_j@wa9ozVhot`L z`^UBKEOfZLFS%G)3uGy3V^F{Q>VeW>@&)nn)z?4&{M}EFAAV$APltoj^zwXZ)kbeb zC@e+Q>9)VWUY>s6TBVDA-k)Oa^AX4S{`A!s^C{1Av`ur)-Jgzc-eBOzzyA-@2XNnTmm;oglta1xZ5To8P7pKB7=@BY|FiEsETV7E&Dg_v@ zOfiCpMuZ57S#|aB(IOqdj#kI~z#~vNYA`&!c*@;`JCG^<$~L1(e2?W6-XLJxEhVa} zuw#Bjwn{LPgJ%;K7)Z=}$jlxA0y60q42VQeJbEORz6BK*1e#bfO~M}C!JS5?IS^ss zFoO~aXb1x28qSW&@Dbx0t#-p0t?$Eb z`*_;6HQJ_Q@7>TxjOZ(ub!%JY+t%2l@8DqMOj%VW7b4ggsKdPt@374~rIbaE$(yB; zL@X`J*V_mgqY+^k4RTF9V51Q!;U01%v9S%xwGD${Lq zfqKAPBHX-N8hfjeob~ZipKsY?bXX||GlJ^A@9WxcVZy{=G$JMbtHZ>c^E@BCq9QDe zCh72bIkws&SR_Sn%iWn>%AAkW(#GX>>ok>PN@MNKM(swaC~FZg$?>$TFIPgJblNW~ zB?*+VZ>)Lr-IM3@>xjzRm0Wm`_0B|Qn-I@;hdk@{czb&MM0z4*S=wQGb3T7b4jU`W zLdv34POr42>$~5-`nSJ4)alQE{%&l|wi~nDKfIMRM{TAq6s3?%Q$Eb~ef{x=KPaZH z-Mq(qKIcPu^X1QPpTB#2_XnNRGT#-na`)P9@BjHf{o@W<0yHu8@Nh?}w#QH+cN--v zRO|3C1VG2(<5Ujd=UZj7&5+arvqnA_AEr4iY^5xkG4&|H$E-q_j`MlOoSBlU8H*BX z(&Rut%qfEVEhuYL7K76k`{T#)`FZ`*JKx-nOs~GWI~CFine@w}E=wZI;Gv0$VOGW1 zQVxI<`!taervVVa%3);@?*UNXI4i|W+$@r?vt2xAY&DpK!j(7}(uuNz*&;Ye>|q|G zQ3y!HcO^gus)V`(I95-Yl>kOaa-u92O^rzcp`ayfz&N5JCW;OYGUj%5IeE(*lx zvc9ZwGfCFhvF_IU&|Eq?_W@&&_~;0!yS3YM@YLO!C*1bHa7v@sh)fa9ma#oY2W6?| z;juM!>=?zjZtO%Uz|a)qC6@)(lSr9eatb;KwwMW9GOs-L!KKx1dyFI0zGn~ zp1gOZP)T~2p#%but!+c502{!J>o+R^^?CLscY`t)K+2q@dm`h8c%@>;s-wnXfOcO|RRh z&)0R6$U-Bha(TSGjNV-W0mx}C$aK`HEV^H=dpFxw55Z^_L4$gCr4$BYOht3abK*2j zLH+u)Hiqc3hzur6w%t4^DA-1m6mz$_uK=IVZ*G^1k8U7QA#x>BI`rE!EcLa8`rW)V zv;hx@v6bo6w#V(|qQ}?m_EheEB z`1emAKc!sm&k2aUynXkd{=*MHJ+dJ$#mrI)HEZHqm34Q6FGZ&m!0g3G2PQMpSSzl# zK@@YwoN229mJ$L|nRRS5<@0eyTW3|4o|9@qVZNIvu@)gl=;%~(bnsAWL*pXl&WNb( z9Z{+5x9$DM_Pal>9|otQ-@ciqoabb-wd4K$7ssseV$L9VA50Pf5(Efk;&zRgh(fxD zl1PFNB7lN~pfhuKrH<&Vn z*djvFTqj}#9Hbl)xCUjT{#EJTyD9w{{%gCL;PnIPNVcvKnPh6+JF5tDIwnC{o|@OnBQ zB@?F*Eh0b|!lN^MH{&`2*Z1R@?R~8`U-x3Y?VD{qdhg>FJFwRv8*4Q_q}~DcS(r~n zjY+w8^X>z@?>*KkNhsy1P?=|4rlX9A$xV9SMh#aD5K@V~b#nq}z?opo6G?=TstlT5 zA%kTaunvdosNYi?&*Ugw`dU!=C z@fcDo!4gWcJqu|J3YV$SZYioJnw5GTWJYR)OlBm7)T3{aCMJ-%Ljwdi${aa6*_cnx z&1VeK5bt5VAKVGZ80+vO34+ACdnR7ZDUlI!fi(BNS+e@%^C=xpK|{{z^y)4j7IPA+ zrA&#U?`z)LJaJ$5(X4GZcDC99hbDn`3xbeK z(xSNa^}o44zQx@VeBQ3{ za{Z@QKl__s{px?n#C2b@E<{swUJiHpe6%=b$@k~icR&AH4%29~)=H7;xXtI29+yua zK8M9r(x{D8Fde!iY8cII;;cU99Fj-f+BN8q*{AUt-8znoaf+(gstZL@@`O%qHwX$6 zkL#pI70pR#%4NC)XHaA)(0+Zz5Aj4j$Oy0V4C9C_0<5Sa`)4k;!d$ASlcA zv+)tpH5F)KOSC`wNUF-hysw6WX(rk{I;9M7qzI6~LC+GxY)%u8-E0lKVqSv+m7kc^l{?>b4t#@xu zOM6dQ_2Kcrz&})pn z_7Qc;GD%rd)<{cA#4N?{Po0N5hN`<;CGPI%rb;Q@U5KYuR zBNLH;nZpS)kBvo$_Fzb>9*F^1r#6|`s0N3-w0*69=rma;a~>}rM^Kq(gWWFI&yP>w zDPZnhr5snu;JGH zwmH~^=cy!WnCCeFCb94~hCpo}979RSN9W*l=zg2ZgQhuC4WJZ}G*iy8@4IF3L~*(Q zo3Fn5H~*`rKmNxbKRosBw*UUkH-AIA25IYSgz0olxcmIa|KI$xpP&Ec&0Ttsx^1=Z z?TXIce_EE;OTMf7bIR#-f1VQMd0D2jcgv^v`EP#n)&Kf`ER+5A|Mh?W^z@AOv|iqi z_Vn`nPoMty!X@ioBYY~L*1@A)V~+ubEQdM!Sogt`g|Rnk&}Am2>};}rt z#ENL0BujK~9yAD$0NRKw7)~NQV5#ZYT#sQJC=oV63%T<;AjED6WkMi<9KjRxxf+$k#Wd` z0APVc2x1ND90ddff|Xz#nRz%-kO$}6^Y-qy-}iN=GK+N1(rce*o)N==W@S#SdCobs zP)aeC){T;pyblLFWh0<&M%0W;&)EdpdlX9$2PDa+Z96xHy42 z`VC|EUfb4fjq&;8c-HpP>b`F^UDxq)t3AApG|cx%xU`im4JV#7p`@HoDasPDSLQKb zR!Mj@K+R>g-Ir`IJu9py}TqR;|9rkp3ry1!DCMlL{T%> zfo_4UsH=2ijS;RSqAtXvEg;PZ>h25(#m-owe$+{ccQOg~@Q7)qzELP}FaBaQ+%v}` zAqmYCHF}BZLi-ffVnlG`Z50*UGcga(x2H=Jn%@5W`p>^#N1aZKnI}o(40N zbUtumY~7+V&bGynCX2ui)Su!|_PPy_ro(8MG_GquoF0fgQ{PweAm1)}cMmu^h@P(> ze-tX$Tl?|H?cvYw@4tGuy!+$+vQOu?*U#_EH?JoB_R~N9!!Q4j|0n$0U-a8!c)7-_ z%Xi=Z^uu!*|I_*Y*KfZ3@7nh1;r^al)x$k%oiopO>ieey|LNm@{m<*W&qlJ<>vgBc zy>Uepo!#O%ClzkD-DLDJQl^eVKKYiXSKDpab`26ILP}=4y3}E!he}Q6JFTl8CR-m_ zBpFe%G(&-$Q}1#>)mi7Hd=wfyPl#nbEpZwd>ko=ir9c(yB?Tww;`Gw zyOMkJ;S-5^y+9P*kSHQ!H7QdBc?jm@iLeFYh4%}k>^vw8gE@9E1yv-9aa4OUHyRS^ zkxvkjz7k5fG80)Jm;((8iphKr=^=&3jneF`fL+Ed^h|bx0DMA*?<5+af#{%_A!HYi zgb>T1KEw<_cnT$EaT(Ntn7lJD!stPuL0p!I4lk701!hnakWnZ>0)yCt6b$k~U@`~X zS&6|;;1Nh61~7$&AO=C2QizQ7)i+6f1C9g{+Zp7S9iN2Wn#Y3O=++(S6}*u96ah?AE? z$?TFeR9PygV;k`G+Iiw!%_g*qPbYD}hxM+cj)+C&P{z{@CFQw}{Dt$AJrNxj)fekR z-3$q7TDRwtRWiRoqHd;ctINMxekr0PY6`cA-df!V2(V~ME~n$+)z=S)S5pz;Y-!3I zMWm85v%?kEdzacraOYiP#QNzYg=h+Py_?HCVa}YUBD0XTD2GsTE}?^=AOpZ$nUlAj z$t0h8Ype-Eo{d068Xit1dPE;y0wY@;``&J!Za-WY_pkK+G(LZNd>Qu-XRrw$-hKM` z)ZFUYEoQZ%3t4TKTQl8c(h21DPvd$r0H2Tn7sIK|`fr7?m?-9`*{mL>4NvD=}t!f%NlC#n>9o#$S z#M|}LAKvX|45l$g8q0j2Y`#8y1iR$CoKu?LT)ul>mdo**Z|CLJe*NkA_HPm`?|=Lu z(lThf`|8^_-~5|s-=Dww*{ffEofDk*_rLp}KY#k+^uure=|8-C8iWiFj~#8myozY@ zYOUqd(zn5?BQVh1Wm;4aX8V9NkDOqk5o2B!Y+W=)Ypzn}Y1Cat&yuL_O9BFg{Fp_e z=V58q2gq^|;goU~kx&^-89^&MaYV(Oc(}8WH8Xp6TmSgS^-rsA;Zbi(F0ZG4dR@|T zI8q!7W~BlV>J}+@FxYv5Te!fwYteL<`id5qjtD1#Ow#*KMB)V6d3dB*)O`neGhc{@ zlL~8)z#Re13ZxM|XmCp0Si%Vok>H44J-v#!1u40sH8>+F+`@aLLPY8V*c}{w=U_|{ z#C&^(BV+-%k7$=-h&H}YHE zZ}oP;%dOkZKi_O?V{CDGYTbJqR0!cCfs{1RG+pEUOT(;|)ne(9(jPrdukjimkJ!*z%qMXHzN&_EsI6-^@D4gfW&Q>WBFoiS< z5zoORIzySqh%nx&13moqxPSNE<@+7WtA}#b_P8~QL`5awO4Wv?E_qV5S8rZ{WqWzvhD8kFL_EZ3 z8lj80_pwJRA~DeO9(8(n#oodOk+jx>9LD*6${{3Z($u1)V*&+fz+iQIxm;hK`bx;6 zk(hXF8yAP`>F|rTe@rFwd^pwHcz*xkx#Pq8`r&zN=Ew8G)kY_e;7E%{s9KTZ`GlGK2H3tSCypr{^OW|j z4My1!1i1TXXmt!~R$XD^x3w81^ zDr_zEBx*Evs6v*vfoMbwD8dtm5hY6Gp~T%oRY5G|0z_nhnOum$ z8Zw3>7|K3a;iL)=&TxY`lLv#XBH-)@h7f!>5`_VcAVdz~Fk&(w1$DD&{r>vhKmM){ zV$d{`jef-J$(9 zdb8$aPPK-$m)^YXS2yan&Py~$Z)03GmPRt6eXgr;UyVe-;8af2^t$kA=3<>mWccRR z$&AyXlyffUq|-^}%)%@Tzmhv(+=kVUW3}=8?)Dh%*49g0p4v;5eea)!*`OPAtGyY( zDI&6_nVkrcGlh@c_jS094rTWNlH)84oiI)3lx8ZzBF1XlR$UBX&6yXpHH3RWTMkq+ z4RMZ?bC}LaB3Qx!&MqW@(JeSztE7{y+qQ1E0YMoICWDlmXZi2T-zwPqCizHxXB$c+ z>=eYB5=U9)yVvvS>qDN8%sEe>I%tMQqCAK17}9(McCWr)oyzp|-FH?;XF1V0Bt0rk zhp8NbN#yW_qygqAq)5Sy*h7c{K}mWCO9&A_!k$7sNDCpyXkpbu!8eb2KG-kz`daH`gronRFk^}OBsS}m8ncb^w5^Fyli^!}&n+uhf% zm(#EM_DB&^TGBzm=iaC7@h^EkNLr@*bKdS_|KV@`?tk(1FMjd-hyOYqe=#mURjXym zK$yG|v-SBps^7RJsP_sR1!x9jj zo$3H(q={%4CMFJ8$OO+YBb^C@ri74SB_S{ojMA&18?2DuLNXyD8uApH)EwPSm_bxB z#UN7hooE4wLIVz&0-aDGD&9c}&>&_af)N$ifH2qzt=9SRfBx-D-BXgBQ>1)IUX55X zOV>R-liYSJN#~4Nc{ukK-gyyQBOOIMMWX07oeKx;Cd}3&+14Sr-h#Mo&Dz-7HCnBg zEnag6GG!@REtj=LgaP2%n4^j@Z9_Exw zPC3Y#oxq?Tef6<5N8g*TH+z}-(`|nm*Ozv=*>xSYPq*6F)qSLH4(d|){)?}H;p%D1 zrd+RmL~o77f=lYqk}xfqY?Rk;lREMgwbmXDVQi#{^4aYMp3xeyKxeBrN-PxagBX%E z7-5Xrhr5pII$P}B4Z(f8w6%^=2?z6A1Q5f#`e6C*moJ$Hsc4L>lhP>5oC+n%YF-i_ z&dYMYobHNFQ<_U5@FbkF2s4@Y)+u;Ycec8kbNl%D>BBQR!u)ugPIp>}U)^!ak!IDB zq!<%(C{%b5XGKa%Ky-=}l&E`nGbpn%oO`(R-~)mLoksU6PIa&8{U1O5?o*tw3kuylGSNq?_6)!QOS9=Mj;pxsg0^xIVMehn9IZKJB|4K;r*kL zOfb`k5z$!{DVAAjZ|l~hwzl6Wmub?R^D;>oN9)7-d_KhR_4dL+wRaVA$|JU160+Lv z9y>EqzI&;4i%pNGDUoV+m84Vm2=SE4^q}cS z*6a;rN-UYNTaVU7T-2>)qj};AG?~nm#sC6|(W`TcF(L{Prx?R2CFmH+q)Wcbv(Eki zo(c)cefQspYW|S3ZRD{jkgAGW9ctzyE7IH_nx`=qd18~+H5R@eS!U2*Ltva)Z z!W^0)5l+Fvwg;2zg4jaXr-O_&XaWgF;DIhP@Q@+>->v#1NwEY8fP zoOvc2=ER5)7K|YS5wvZMBgAbT<~oH_zg}CIPp5$~h_+!c8f$HCY})qS=cVomd&oSW zzdWD*R+rajO-&1PW(l{}!pZ7LbIu86%K21snJGCEvlI#-n*UX^vA+1_sXZR*r{|Ze zKYbd{pW_yLzm^NzZHww@v~I%`ln!%Y3u}VOSkVSKnasRIa@CTS(~>5al=9svd4QAD ztBFS2V^?wu&r%;_5QH&m^cXQDF{R8w0g-vhAh3eO9Wfa2L4hvN)?a8?yWX}sglSOs z=;lb`(rL*5^5JhqCAcI~W>?|kRG4_0kGe?lIDK(EzB=7MBt0L5)H8&#a1vn;vml9J zV`C3wjB)+=xIS*JSr8vjdJgB~UmfyNI0HPf7V!=F71GK=@MO~A3iDvV-N=|cl##oT zk@UdCy$K=A(JfGYuiGY{-}hTfF^%Q*Lz>T*cTb<6p4N36X1AT5FHd_ATTBN{(_!4! zo6pI8uxn8fwLmycP@Cvn(&_apZ*_bA&@i{w)gmubAUb2PrLdHExO?kYt4@hWbHwtH zm!nwMD!s1FdJE3ccSAPx%<~xCt(TM}gwr6^A*jBYYwTOByY&(3TBbzCfoKS_?2-uE zwhO^(1a!N7BpPKd`R+9tsJ-Mf;n<)3@sHnG|8)AI%;lGtk3aP1=d}Fl{rCTc ziPGU$KmPf5>-yp0?N^7xp;c$be);UphX}k<$?C?FXiEF_){KXTp6}QOA&yB}Z5Gl- zQzBwX1zFT%>KL(;W+Nt20h5>unQG3cs+64cD6@gJOw7|nMO2Ei5n)ORb@!CTK^~MK zl#FV(#{0Vc*YE9jFXMvLoMz3ZS>N1Gr^4mHuV=ZRG^smh?w!m+2}l9r1K~E19i(6- z>%l~<9164GW+}^PP6^^P5K&zwOG%(kyEkE_kVGC~<|%;*ttY#h&I*K)P*^G$JrX&L z8PTqc;wh7pBbXT>4vRJd%!!%maD@uY#2Qk854e*sdKK;!@_Gcm%6gdL7x20WP50TLiAAfO-+At(k@P&9ZDHPf=ad;IXn9|#g495gtE zP&R}n2_uE5@S#}Su@M%;2to_WkVq7x0|+4k6V>h{)IAu;V5lp(s}=4yG7a#d!UfcN zxN+@mAa(QFN9#N<$8_1IFV3&Oo*#a3EU!vg7EK1vL^t?|LD5zMz``o|?m;F=IU%_) zQ4pxZHyYyOWo*r!>v*|bKiAvicG>9V(w+v3d6Fa^PC3ECTHlA} zZb5Z$GCJKA^`e3DM%!~a%*|cqVtpT&BC5fOA_8zDi5|(lkCJm}aHm0O(#-5$IiFnE z+8&I-B-VS|tj5~Mh<586Kmv9Q??G-pj0o~S&VNhJj8Ul0OPX0qE?Jp-JqCd>E%V)* zhdi@Rr|Bp;mCV6e0AU_1g778*h`DSppX%eSJznd&XSWPG9;QkAol?mvDtVql6Xis- zLrN%?4!+;7VqW$$Go4^y5!2CU>6N@ry6=e5~(3 zJ-)29q4nDO9*wr%2Gyy|&G!A)N+z)9qD(v=O5cqH)0B>{&%Ui=->>UVLf4D6w9olC z=P6?E>zeey$(fa;P^4}Hpdg;Il$6oO@Xk#f#z{DsQ+QGdLcNZy?R(4f3>nMeZW0}J zH!JS75|GcfbxK}j4q}Gq^J#A((n?I)dG{*87M11j`23mbR>V_2+Qxi+JbZgt-h7Fy z(H^#Ux2^sluZzyVe*fv+%j2I9)4zJWe7BtLj>m^?ykxnp@7K#M(X>CmcTaFHMAN8g zQD)eRR(l^IBHnlBC8cRPp8I@f%e@>I-zzC=56!&wokt9&q#1BFav$nr<~*PEFsFH1 zvh`ERnpu|esz9TraxcA=Bbh0}$9x7TG_rIHXi5X#w)VU4_8&iAKD1&ZGW2x7s}tQH z^zJwvOMY|82X_>YfDVU}&#(Uf6ye#gHQAXb=KbDbtrZb_IOlv5Gf5U%Lw8qI%d!CZ zM%RW7_}YK4;Ts#a0jW^xZgtndBAJ=Y%x^x!-a8`JdIwX_quc|Yosv<8WEFye2(Bzc z%YyxdD~Sy_5J5bWiU8~>)*+byhk_GQ!IeFPYbwh=2o$xlAVioH*a?XkDMxq`3APU9 z?6)%AbJ=4!duC-$V^9!8glr@C43Gw>fie*ZNp}*6G^1|*AfF>;sSdoo0Ii1^-wXkhSNhOXIkx0o54rZ3DjgnFtM z0$3tKl|2DTDnyy#DFP8_p=7#bi2Gm|@cK$sjH3|%++@GpOeb^-nU=b! zCIrfEmQ`hxxe`@yAQ45$hlmn&K;C3lB97n&b9-SjPCc9b$ zjGgO(9q~zb>xb?7l0Ut-FP~!_wq0#VU485p2`QY1^YKsw?81YC7r?xbe zR_kF}7Aj~wgDFrPRBKXZvO2{2%XRzueEode`+mFJM9V>Sp5!=}(?oKB%&!X#5r(N& zBfY15B$`+<;3APbb4ZViXj5j+3$YO^22<$)PVcg_CA!7+#eW0?j2%2#5E|OnhoXp z^>J8QvPDw22vp_SW!v}kKGoxLs^LUUuIqD|mgHuAFKp-@l$X=emgCW{m;LD_Jj=v7HReGCsxqi0mi&^k(vvg<~?w-V=B}OJNPfIOD^mu4@r<}@> z_NQ9wQl&Dg(vgKKwT#kWLxhMmG*H~hI-P$h{=8GYzFdF)u>Q->`}d>WNJzQ0cstK` zC;8?`r={FiKP^l=FoZ~hW>MnYAxf6a$#scz4uCQ_*h~72eRHlJ#$E&?WTK3O#7M5} zdY?Q9q!=VXnR2{<3PDKMc&Z$XGy-|4AXTV%XX!M^Yvr+0R`LzhqEz9Q(RmASCT3Db4Dmg=WKSW7dT@mp zvL~1er4=rPOK=n!yO#PGD<<`R;8kMW8nbYy&wkIp(zFA!OGgMBM9p-Npufd$B>+;@GShz+xE?G zUcdcyTfRM($+R&2nXu(moc-~8do;f|1oi%*p3h|_QRP~gMQNpE^6s|zb+aw)+?;81Z zKB--dmJvW7W^A3@DG9#W7~$!Dck(aSMA!Sf43yS{yiPOPfNS*O8VmD!08L@l2SNOVV0|DT&m9RHktE zK?s0_A`qNG=tOHB7=#{U*g8n>qtsGyyxu2HOZEp|G^}f1>anAKPO;gk$ZX@Gnt^^96r^ASq zQ-AUHn_3%~nnP$mXiVqhm!B?w{D*)1@a226+P!W+ZR^KB6}i=Sb^hkTi1wH3hLzj9 zxV>mu=U@C)5d zux{1?(NYBUut4RyZpJLLs{1rG{xcg9Q6vkE1%+}|kk&||xzLn?2=x$wI5EQV1}Y$P zb+r*MACNY#m+LkE?SsE}GEfr4b1L=WzP^4t(KOHJ!|AYy3za6=U@G;(NK($RA=QRc zA4&rZ@Jw7$kbHL1NHDi(8hVUUAd2icO_nKzc$n`IO%tB1pa>~ROc79|D~(&yB9YnA zr4l%lG)3eRUV}!~#?k|lRH7u5la11oHIJ_-N0{=wBq@r3$x$do`X%~P_#Cc@q_H9j z@;O+8cG;i3zi_{y*0hS~NuVM*&p8T7x&%gI-^h|OqqJlfN!JVtQ;a%=Z)9-KEQ6%8 zD#Te_F$g26f<0;@D8i79MusejjAW1|Mj##jS(I2+SQe?= zCPrG9Sq?>FT@hYMV#NLNWL8mNrSjcd4!T^|%Zsbv@Nm3awsx;lN#xAjM3YZNl+B;) zWw$lcfO@Wrm3k$jP^KKj;h?lYY|-6Z?D6sCYkqmZ{ppYE^Xj|nXxMJ+5bhH-sl-&9 zNRDd4wHtJd;bUJnVu_GSjOufdLc-eq?4aj+OW%>(b?ocbw|y9!UG^;p)QVYI(1Zqi zVZmg#H3gzXdQ39qsZ406Gm~4)StOHTC9f-IkwZaMEaI&Mc^_88nM+gRSEtjf(`jm` zMGEOOH7a?SUzO7`m8uUXm5Fojrep6NDZ7o)8$WAip<5{d4)qO4g0Qf(gC3cyOjB}; zeXKBK0_4HL&aC9%G5|41A>Jc3P=bQsiNe{KiI`K!)gu*4z#Y7yAvJxs9R2oqdpJ+B z-R5=&x*LSbpz5d0kQp|m`eXKX@x0fQ~ z6d1!|WN=YRQ9ezKl9qJTI%(LRx4n}!piPq$agROovSpBu7|ZFXl|swu%{xb*T4758 z(umD66gq>fOlKklTbt3!B;MCGU%otk{P=yU*7;DUx$A8{9nZ_Ws2$EnlzB*09})TZ zvj6=1e|~)bpT7L`yM49s-_Iy3D&iE58RU<{dZTv$ag zQLIce(}u_tChw>VNV4~G`AW1f1hR2=FO6&vjK`H=SxbsXjMOP~qI^LvlwjY_$ z9hu=!TvxVT%29Tri>V4N&?GsuY)k5@VzSiANwo-g1TiTqYgy6=$HMcpyt$t}BC{-& zf_+_8ZOfY;Dh>-rTOYq%2RW4}(UNN3=6a>+pzK;Y^B_*$oOA0V?Uoj^9Cke)WiBZS znIv|~K@k`$Vz+_5n_q70=XLwC{rvs*OtuHxpy;)a}D-_NtudI$_vf>IbX zv&@BStJ7Q>>chRXRt{O_H`*$*<#a0Q6hsKh;``ct+O{qB?k|t~)z{|{qpRa#uG7Q^ zHFqi8w6P+2+>1zJEU)TNKP9+NiZ$ zH>PA|s&m|)ZDeb+vvWK2+a*S*kSLFJ-^>o}P!|>|w%zQ?a?D8&M6|DKvTo0}TB{ay z;j!)A(pZ9-ldQH9(T6pRf|7f3$x^0$Q14cy+~1waisQLxD=Z^qtm}GPQ?c(ity6Mw z+a>Pz^&?N^^yaVnizGd_)9ZG6J>9+0T5#F3csu<%A3xYA?fA{JHLF~XXU_Sj@BZs> zn{`^4MXXclBK>yLpbQ?gc`BH#yN9`DZJwyx)K#{{D7!bKxn;oc@Wo=k_j8Uimjl#^joL5LYrtwv((~|Z2JHKhH?z>pTXRxBliJK zV!(R@1ef5-DV*16CmAaU$n1QC8A?$y-F(PVX@xXcf>M|gd$5R)a4-{zz%rqTfLJO7 zH7G+T^c^KprVxtZoWiw~|X-H5~o-7-;~PgAquhl*x)GAAP@xxg?D+kSymDLNYs9FT@Dqks+f{CD9TqQ~AY0 ze{qWYzq+4aX=`UyBJQ9-x~-4>%geY~ank8jPbeqRVnmZdi9M4tyY<dKM|*gifs;OHr=NB+L$z zX};XduFo5IjNO@X?PKp;#H%y*$inbQD`I)g3d3BeHYpPX(k5o{%QaaedIy9U?vCO) z>O89u(jr2_N-2X4JyI%DYt&lOKsy=>Mi)t0M6|$@d@a+YR7#BSnzR{i8KwA(S&1wj z;_;Gm%Xs1?su&%oI+aok#BFX{Xb@5+vWa*jFOCkL6C<;w-Ox))h3-yFF%s^&!@Jbf z-b*XwrovDn9cfLnq%7$aqH-_mbYkB7KCah&d)l|#Iv-1fZkvrhs2qbGp_l8n9C12K zZDGqT`|az`?_UN5XWC9T6V6z#rBonmnS9-xuW-lvz6<|75zqs|zsyUZ32@`kQ z?S*qnp_!3Q55!qH59gDonfKUt_e_?wOHCxX#t2mw-BEg@cGu>^kvzhE8>JU7lic6m zap=?IN9ZKO5;RYf<}B1ot#@S(fzEa8?N9&ffBO2wS0n}b z4x#jX{Br%5-#`7gFZ67OXWvi1{>x**n^XOZZ%)U<;q7AQnv%*B2|H{hEhICf#-XMg zWF%TLBr8TR0$`!c9K?jFqW=0Rv(MLe6G(?YKj7-~O^hhQ5 z)Dz-!LP|bSU}W{|)U7xnNy{YgP^D7SlgPz)CPO!Y1T&YKg}93q1JA(}2^0&AbQA6B?%wmGr(1EwmXXPj}4#JGY_Qf<^<_E_%Bn*vQH- zgw0M$LWg#kCYi;rFRa&cU-`6T7SVJ^l{&IlB0AhxfYO7K_9^yT#^V?_M39-gc?f|S z2byX3a1|GX_9%OawtN2nz=AMV;iAj;;Ch>8G-14uWF2p+)UiVM*?oUMvIA#n(}}B z_1}djg1FY2$$VfXV$s8?RIsVeQcepA)p@DQ)N0EjRf-EUCr~2Ox`i<17Mtw1Ew{Zt zuTDA7Z928X@TvMV0n4E(ktktf0mxW13WJ3Cqz21p+a6^(O+u!0y?7`Q*YR}S;NWHChSjEnx;q7^a({k`t&gM*kAU4QD0r!y z=^*8-TreE$KCG3A6A%rCBy*3dQ}l0qQ1kMzzA_h7DCv!ZZCq$irM*FyXJa607jb$c#)u;>P-WtPDll4F}| zoeJ|2)Fb%t^5J_MAGAGiDb#Ou+lWV~vK;Jj`_uRTd|IY*nC4%+%33d%-+%Xy|KH2k zHAl9lq}~TmtF1fLMuUv^loH9F;hB^^%QEa5t2t8^u9gET)#r9Ex)w+iZp~W3GBfFGWkx&6GvvMhtb_#>4Ur~8)T&Wm(Tr=KRx}^&;EkExfdz1UVr)T{^HF< zZ>M}W`J0Ei73f@LT-lZ2;KswK7TI1xEA5u$73Ux!s1PzsBO^+OYPu0koE|xd3(`Ve ze1I3&HOnEn2t4W?GD(@Od!2wG9bP783GTs@VxTm@oS^%j01Jl*BT1Dl80Trcg(JX2M$ zBM{kH7t|hp%pBf~WFa=j2!{Zi4wnot&62|nlmuZgODJO|Y$W%DYw9fAf;!pAT15x| z0hCGFn0C(s2U1vo6t3U^lYt4CGl@K*Ovr=_BGV(g?|l9F@uz?NKCy@lv{XIC*rOF9 z5R`bZC`*z9L|s)QV>gfD*!g%D+inPAW>Tg~W-^!L@O6~K6e#S8LQIe>n-4Mev?4*M zNvTPP?BCo^Z@)R;zu|JnJk83+NQj2RoPAVLk;9o~=;0vKgu>z(@XX-xvR~3K@3*gh z{c-#0kI#Sj*ZuvIycWWDW-i)FDN&SD3a3{4`oVkl(KF#| zr0s6ZO^BgoUT-7A26&7SrKI?2o)aYhmtX!}I8?T9%V<8HAq%HcjSQ+~k%{PZtcQax ztfyLvkSw9nlmSi>CMyJSn8&*DxZTzs_B^gn*O~Lawj%pMv(zFJmr|4s)0wJ@lxSXa z0+Z8415u60ftuKfW-dl4#1?6p2JePK*?q+Iar^M|b}Mgr+sks2Y3ytJ{Pe*#%I$XB zV_y;cLa6g{av7{Ny!i98Sp-*3&J?LU%QS|uxdjPvbhCkSUPvYqI=(uW66-#MHIq`K z-v(gVZb>9O_DAcHR=OVFsCr^lS@!jLT`wqY-^O(vMT*6!)1kIzx0QzSL;|XM>S>gn zRS)x_C=pdw>{oN<2%G2AuwJJ##ky$|S3{rcX?`=$GUNZ62l-wzAfWh7m`T>kN&pa1jc@ileipW&eO-GjbEoEG}!lFRXYTuRd-qbC&- zC2GPHS}1PDiwKel4yu3!*~UdUG*bwfoE*Z|yB?XYnUjWRn+fFFB(6N2aCyNzMK-1_ zStN&JMV^!tG>9Fsuqk{`Z z0yi4&QWFpcQFlFpg9=z@7~nTAjogxhQIQ$8gB0Qbzd%603@{;G2ohlCNK{T{ZAb^e z1a?m?lnOCs0S2d&?*xFEoQMP*NwmJ)p8xdp{QQ+Ts??#xISQ53q|LP+D6ZtBoWZP( zBu2Id2_(6@ZOIRJ)CW~b+cPMxD^Y4~h{3zF*yvW<9HSeNGEuVAD95`-c{on9PE(Dy z4}ABkwgshC(L!7qo_Qn$5cNn@wbV)YDpS#NO!rsOi$Od!#Os+iSe?8#=7nF!l<6L&Af%A%Tn4Wa91 z;+aI@P9&vhM9Tl|w|`3n(uFDmo-9nshe@2JPB;p;sTR>9(x}aqWtOUpk)$EalqLbE z$l<;3tA*ce!~SxK=j%b^P_VGpsm)WAQnXE3ThS1Bsz^EsQ8;;J+99W0DGO0lp=1Q< z8Ca8?yeB5mN~u0*d$#wV*Y)rqgWEAD_BGqnQ#VQM{L|AXopiUHYCWjf?RoE=P^3*s zNl|D@%YTn>C`Lqp8&L=mkVp}o*;j=Ek{rPc zh}V%)Cefr0X`oD|>cfaP&zZwvJF&Qnj28+|4${iqcqt<)@|p%7yYnDWfV8{UiDJ)4 zGD5Bd4yh%{jiWR+(C8>j{25UOxESaR4hrH{$u`o+ItMDqfHA=x$MJu>uY*`S~L`IOpW{F5H zq{!@WAtoXQGo+Fe6#&9y2q8`|M><5A213a@i&7+|GbG&L9cW1`Dv(4bcx?OO@xT4o zm*+K`2(%Oe@j(MvFmsNLs%mOSBBt1T9|VeAcb(5}I}x*XahBm!1s*}EN~lu`dDtF9 zOXWU-oI#*y7*&)mYe7y#1>5~}I81sx({y-MmPJoQ(jb-boKPu?l8XfKMB)VEkXSF7 zH@ouo;p^=&pMJW0`R?-H{?Nbt>@VT_jx}hYCmNUtXt7TVi8fxi?>ouVpI*9^qE4c1 zo`s^#RpzO2p-M#&G%?Bc@fiE*y?1r9m%AP8WSZ`i`?b^{8#^7FxS$egU2rC`>F&8 z6g(dktdq3UQKv(2PNy@qMjWCXm1_V@8XeAo&Y@fHzPera@pQRe_I7_KL5tdPvU(_@ zlb5EFad=Cui=`E1u9==Rg3h70A{{X>3B{gM)qEi^4PdEOr7r|&*KU-Ir@#1e`9ML-wA^~I<#OcH zZ+~-`-#mZ#czM~U1C_ZRU;l>eC8yK>g9&QKw1?GUH*AJ27o8-+y@d$M6077yh&wNv(4`9_1Iu`4?{vzgqZp z#mtxwhgncz6xCwXGAC`KB}JGbyMdFmCI=`A;VD@W&(myB00GWNv5R|$4Xpn z3~7ZCri*O1ECLEpNf(MOsfjR~3vEV6=9SA)!ZRWoE@ibzSU!Vl3d5_6^`8~H5kl!+2jO2!}%xl!~a0u9cYt9k-nxJ~3cP?8EqfRO|S z5iw5z!rLGLqDp ztBPb5?1W65Ki+#<6m&Q!0Q)V^^YHbpteVdPmirzR| zWvyHay}fVqn`OFR(25EXx#IvH%F3+au0k2N7$dEX%ZKqy+w=SD*N5j1A3uD5`|y9CBQ zs>PaNs}k?M4{uYWeZ}w~rirUA0jo+yjxtkiCuAp4E`Uz9y?7FCd+%oBg36;ayeFZL zEtvK-02@fL;=I?xvD8T@vnXfJ>^b&svhndydS`=9v($;nOPxeqxQw`naKud*jfs@h znPedLGztKt_cTsQ50b<(6>)rd%qArU2aV2vD|V<*s`SmlWn4iKQbQT}B0by$Oc?+j zXqd5NHj9$cJU|fABkz}(8`gYUjaaG2uWZrTe0gy~}*0PjnSxUKo zbBE*}9HM0CBd*V%sftdmX_=PB$Ax(s+il!TI5=5b4MU8)y2mxRmd5<*n{Qv;9Tx#S zTrhlI*B8v?H}8JC?>A2tua~i3I`x;Qhc|bxUjG`P>sLH}dVjpXfA!7Z{OZ^5j(T5? zbL=nc$GE<~UB3J*OPT)q?V+CE&Sj~x)W%gi*}ivU>4o{UaCS5*g6KE2&cWv9odzq9 z+`+BXGB4$zbvX!85>byPm?h^18|G_BEA_t0GA*-KAoc^z$0Ct@>H<^WoqE{Em+im& z?#utA(iXB#0J)MWK=2OnJSGFO-rz2e&=?+YkttOy2qI8!o> zqX-k|TlKJV*Z7P~_^-(-Yx@U?R@I@MM8R#*T0*>;!No zwe*%{AS0thIBA_Sm{_wtoG2|Ki)naeF_WfBNa`zdil%Gky5<*+=H{+ArIxTmlv% z!O*=m>N?Q576oFgqfk156MbBz33t!R7~Vqo{&nh{+`&tT`$qeS=-h9XBT*qOpbSoM zg(U^$wyIN+#t$l= zwsqgaFOS>fRoZE8$TlB}&a-l@B5KoI;+aZ=-(r5C2+3QLCLD!Qh_g~*mb zR0tlvWPgG6VdcXgKYbj>H-Gg_%K?k8D|zSrKlZeFYO9=1QNw?BQ} z|L1>R|I>%-N3e@vj04%5DSz{J{_P#Vo_Kj(D(kG&N)#_bhTc%_^uyjG+<5XhDRC&LqIy}RO<4WeV z2RO2sWC>yp<*_ASL30XIfE7qix)LN6Op*X}AZplPmXt;F#Y*Gc((jFv+k)<0fE31Xvm2xg;mDB{`7?Pt2As#DV~kBnwe8afWb$a!Y9lCm}>4$i*cE zC>)(iBdkOW@%`GK|M_1(e_6*|gql{So>Wt{xc7ocOu)!LGZzwSO?OYfB@BGGTbEgh zB`IiiW@H*^m=P?gke61-gg{0#OJPZh>A)1A#4NSW^Xt2Me^;k>=W-wQ@Jdys5M&}v zs*!f2+->Wg(QiCHecV2+>rEd&t?%FC{r9)`U-PnKbGin^cSfs7XH55p2AYaY6iwMk zG8u_L+r~J|LWg51^W+^BQ(NR%86<^cADe8RPylBUqNrVTe1T!2}1XQTZn^;_ldWaD9w^Q z*OeZB?q7C1ynS`jaa(g`^{cNKU!SkL<#axIxA~yRSg!#EgeRH`&m)G2@Kj=VCT+7G zOY?3?`*70bnEP64p(5I**vP{A2!=S2`zFi5p@f{OF28utJ{}(4l-xJ#?euE5b-%4+ z8((rvXKL_lrOsqbIE z{q5h|<@)LRzG}UH`--mPW;dY`dzLfEbiSL}UXJe`POoY`AF1c%Pv2knb#C_`{^^fj zzkXRSdpo^8%&)dD@7K$XCW*cwD1<^H24~pZT%}^F-h1Q(j=dAtFu!n zEcM*z*XQXs-z?ugEceZ8U5aL_=el@HavnsL$Ds2a_lv-JRzgbUv<(Vj;_M`i*{B9w zn7YNrv{-C@)Qls>AbX(zDW#|YjtFX?$Yd5EnZ>fSAR!D&Mk@A4^8^e=5tc=f3>g{B z8JQ6*>Fljl-!i702?j>;cuAhwMuvq}sWbaa_9A}4bYN_N(rV6J(}6iLQX}=0VFC&e z0S@Pwr~pn{3&h|^BzXzWoR`dGYQQc&aw^FI8EK3nG>oOPdYYllnMU1{B6R{AR1*_d zq8>>zD7b2b2s_L&lPaJ>4!CC%vE&k9CI+#D2QdMXNk~d&fWZNPT!2IolE!gyOhg&5 zPRshcA3nT);jvSjK;By6cH-NGxB@$(vQFY{OQ75_iNVu>%}O1+eTLL9!!VhQF|{X+bnIKDfY;Kn={0$ zwpxqVskVaBsxA}i0TPIb$aA>2;+t(_(0&Tqu<_44J-ul`O>^8ER$g$Bpn ze2!tFyfBAgs)yF3M_+qS<-Xsf$CPQhWL#&#{V)FVdi(P7@ds^h14i6?mgD(&dHi^| zm(%NCKYsYI+2vdoZJbZz%ZCq#(;Wwz;I{89Q(rH4Z|3RMt0FA?tKnbH?e%uMef<0! z;YIxT>R0yld42h8%MzhmJh$Z)jh;vmsS^{CZ)U@j$lWCdQ~^pyuP&yA9ajr75<0uL z!*&#xRH<=dUnEqtg8A5dy>=Iq{QA@F)BEfH_Q%_Q`RMO&{*==QQi=zO*XQN0U)OJ6 zm2anVtPn<%b|_w1m6Rx`G*&IXfm}6%gjp#;2&W_j<%EP5H`m}wcFi_(M(`9+>CV{6 zL&}}YP?Xd=nzpnc1V|{D(32-lCJZ6rNajqWaV6$F95|hdQ#n%+>N}UpyhS-y3zH&a z1Wg2{+@UQ+frK08=2+918v*P&gV!Whc%TqFNg>}-s)ReB8Q^9pH7uFfM=F6QQloO< zeaqnBg%k{MfGr?P@RcB3A4mv0KmZYv$wL@m2siMSR-r1xoExcV4ia)q3{XjU5G06` zg*6F9k}{Qm!H18|HJo~ zs`b5<7STCI*Pym2tM4l>hX@{?M9u`_NJ$@-#58N+5SoyC_Ca-tSb@^Fi%ObDEt=5C zq6<_?tE{SxMAJ1*MxSeYIO+ZUT<*@(38gh{%EgHYxpS=EV{H5QeBGbEzWjXq`WR0? zU%&ft`@HJ)a(N!jZkr>9M>;PmQ6`CgzN^I6nF<$m50dLwlOkd!)a0m#wNfJrNSY0Y5lQ#j zu#L?Lpi*V?^p_onY3%#;d39!PLK{k@I=5QLnN=|QV7s~9oHDR|CL+&?vYU;J0n(jE zc3Q8SuP=_-cI3EOxQ;b$o8$xpJdv!!1tYliO_PLsBr~Uc5B?%ev=O7@pE~it#>*3DBZ8u477=4y_V_cGdjH#B(c{Jr63ZbWT&lNUzTt=xM)lla}~Evxq4 zMUSg_Z`{I|>L%AR@u|Muw(_Tc{Ri)>=rOmK>-!g9<@gM&4m;cxAp8ntO^@mMAqvYMIySvjb59P1k-Tn1noc`|3{a?L1 ze0#3PV-qg()TX6ORZC6cgiMtoWXVJWV;unHwt1b&vE3qRelR1z80htIW1yk*|D*9*q;{^DasK}=-61B*nRW`<+6<*=A-J-v6-8D`!Na~3+M za*V%+RzHINA0QedW;$GYn3YPFWT~ z&oYxTIyo~!lU-{8DPa;HDKqVrq>u||XFu}J$P(g-iiFT3*9vtjB~72N?w&(2^04>* z^z!V~jF5>A6~}QpMLkTp6{eg zb)Jq7Q=1k(of!c6(&pH_O0v|$JRzb-8Mf7?r_-^iU^u03x0f6>zdo;zy-Y{+PB!1Y zK7D(-qd^|?j;V>!U`r*0TZK^t#Y3t*|$Dg;S8;11WA&bp3=I7u1{olU3|K?@e zvzKvwKE3+2oWoLfJk5u{tBAzV2efYveeAgR!KQBg>U=5%O>dtKV8_^LiqmciT;*Ns1X+W+at z{U3g}{x3iN@UQi+|LawLWW6$7jLPV*a{r5FfBT?+dxyWdJHI`wN2~}-bg3dtjX}f| zMLh+^Nf-fAVj{rHlx@P+Ln(UA{aMCf)ez=-#CReus!kpPmORrO*LUBs1X32FcyaOwbZxOJ%=_WzIDzk(X>n?Z8;QE(l9xv`MH^fYv9X zM&pGirnrQ$T2Z22xv;$$J7@mAA<`kCw8p2Up7S*sI$x;baL?b90P)qDUDCAPPWW)?ABzM(p&mh+zX^l5tO)IEQ z>L?1DIfxBm%()I5Mf^*+x)&c8AM4m@-}ddck7w;)bNkw#fAH`Axc&5^>n7&ZYOCkd z5Hy}ftrWp?DN8*qSdItLn7{pYvb71M@+8h8$8hE#I~)E9p!X0la#%87BEi2I}r(sGE_84Jjt&wC=#WTx?7sXwmTU@ z#?w`N7*P6cyR18kmNCktJe7c?57IrhbsL1ycS#l(kC!@2$uG?-SjXa!t z@SM&z$FzNZ`tnjz>U5B8Y*Ehr`SQchA9e@n zD9OqcI;PXR^o@$ncW1xc2*HJ9xMkihTb(g!YJ0Qx_d4D0{pzEOHcHI3UboBL@-DMW zmh0HvwvwzYDa1^p+wrj6-JgWZ?e?^DdH3)BW_D_PN+Ni_r!`CmjZFRQ!a3q;>d!D9v`}hANzKoy$ z@J~ajw5dN|ZqJu89f)_*xI6!K1YW)UCHu?aSKo4bC8Nc*zN{}HUfO(jdh_MOA6=W0 z3?pL)4n((lcvWW|abcQ#_il#9V4k#6f~zdNlv<>3ia1uTRc47sDZU3;6Uyu_FXQK* zpTBz=KRm{l4WDg)k#9c#^uw0C=&_`|TFTp_{`yt>i?f_3dLywkYehV$);cR|r6$Ug zfLo~nry`zI9FvNTS?!zuAlp+34=Lydt?8c2J&_R=4^Lw5gCcNHN27)`&J2+gsb>L7 z%YoD+1TfLIIXrSE+TnpRa||K|1+XWPI)&QcRNI}HgoBN#Aekt0c#?<^=k7!qh{_0( z*lCO)$_P=RDv?2Lj_B+ac@;Z`5>dJ|+Pji~3?SD=?Cbyr>x2}H3nHjZF|P0=W`Nm; zG7(u;A*wMzKuR*0cmb1=2QnKW3)9GC)(P3NC7uQr<}mV zk|0T10iiOpdODF3MFs*i00v0hGnhOwEr}QcN)Qn{GC&3?!*l=o^7PZ!9x5PsXo^fq z*{DwJnWTz3ytngW79vQgotTCv2T4n22r@{EL<=a07!KY#hrzx(5Mx#hNxb=zY;F{ z5nI-yPD^2rkvGM}_L9jM2=KNAFO#q?tq9B1M5V~7(|jj+O_^D-+s!X~cy7;Y?>Ar9 ztTUyB2?io8+`{&GZVl2f+I%QAG_%xMilnrlHBeb%IKg(15{AJfD0Q>7?EPw2bK7rg zpQl$MH$C6$x;f0r%hbZ%c7~(_^52(l(xbEqGJaQa>IU@aL~JDn)&**z5Z>Za(nuE|MsDw zS>Ju|ZWjun%smq%Zu{xfmeYeUfByLBtSEAKXmfovo^LC@{PKVNtMjY>aQ)%O=iAS( z9{%R1$3M-7lW*I6`gXrv&wu&bX*r2D%`9zSzCE?O6W5bIef;?QA3Akmy1akCBi{Y; z*O!k!tt*LrNuN|LZZAZY$G!vLndb58;kWknBc%}ujV*U0$y#FxcP*Oe=G(>gTYS9X z{Y(GTT0V7ozG6#UBh7O6UP#WwXYIdwH@|x|y({!)=5ymkwTMcksc6wEDpiG~R18Yd z<$%$d9kORs^+6c`*X@EdicSoc3}KAH;p_xyAY)|c!flS|6*WNQmiG@BUTh_fG*5sL z87aS_7{{nVizdaM&w`y z=1`8T)IsKgjkQoPN{jwPtq}yt?192SO(ubaDJFmuS(1svvItwr93;YApgSdyfo#N) zG(Z7qfD#;3U;%OR3LS~UQZqoFBn(DCK?xSt0TP50Kz1V{kdbhI!q5NmPh%ucsI>$& z8!KT;X!0H?A*=Es`jEMbq;nM+C2As4glY@3sa4``R!eoWV^CzcPFjjk)LML^km+@e z3kqwUR0g?)AUYT{S9E!0i z9irIj{xwVBiZ7QBbocP;_3PVr-+lS`vSn`9QRQ%YwW!o!n@-2O`)?o-z%<=yO(PMY zoB5e2U0a5bcEP#_TGr>wGvP3SYysacvx~F;;rR{6#iEPhIjxdiD zio9cc4&g|SmJ~g8aC#D>fNTRu$&wKM0-8Z!uI#&~ds}!n;+~OQ6CN}vrURuz5ZIVc zHuB2$pa#{h2XRm;**=nO3Aw zBBi148WN2-IT(y2q6pGNmO?gCh1uX6(Xv0^KL58rJa3&y#XXpWgwwKAn1n=b$(lKK z)S35S6&jSnIij)|_rjC+jWW_B7`gZ0XoX?a7#uFsr08K(#kkVs?xE8>HCPsw(8d>? z4nYyy*Kwik`Dy(+Za+MI_;1hO{k%Qf(pU3h_H<#g*!#F%_KPi*D19l)VVpqpw(Z)Q zGVPMtVTtgdB2zt1m5E24COH&f!m$u#aP2Q&u;;#akI{W6P+Yp_p9Q~M`hFcDlmhjs zwzg!Iwk#y|Sf@e>lEZY+OiAacMatQ+<~Dh5#KF<*w%dN$`+B{0av~ojQcBy`PSk6s zeeN>Pb~Fi%X*LWBx#5+hSdg+GHLI|K(}ZN#^fztx2054c;ZVwK*XMSBjCITFb=_7y zHJpEieAc}&;QjjM7r&_WZr`3iUoVIM@YgTD`_aeNmOEs7{QUF%tMc&6zxNN1A3lHo z?XUlC{q%8!Rm%H^w_NG`>H*`1Sh}I+Z8}V{I?`u3T(4gv+x63X5}pqS^ti5Lx69nl zRY}~p%jUQ2h^eK>9N}mMwi8+*!oFuDh4;kmwhdl3-nu7%p6+nHUQQ45{b6~l^7e$+ z;%{cTyUSOP&u@6Y*A?J+{<6eAwNlusVyRN5r50^viAhlxf=g*6OdYC9rBG3+4G1D8 z?MV}{<>t^PG*C4lD8?Di5+em)B9}bgNq>yAEQhqKMsgD*vP{@-p%aa(l)~Z2UFJKo z0ouqsF%fNvNv&f*D1ppMW)*M<1Qf}XE~Fr) z^dK-}r9xQ>kRU}GNRZA&GJ~Nh3DQg^FmS!u@%dkVdjI~jS78Pf#THorE16wNqm)bw z_KX0FRuUJq0*h=-Nt7&PA#ukf393ZP5w_xZEaA-BaLKB z=1OuN*XP?~j2F9o+P{7tpI^#)_07mik!{`5V3dv$kVBzvRf@2o6!4%>vxQ^ttCt;UGN?bDVZvrHe+BbXw^&7h#rCd))PyqczI zVJ`Jp%t;z3Jt#0QCEfZ}IK5xPi^Z1h*f+$u^lMKpPC-e`F>FvKC6PHA!6;ewebZ8I z`agnXCPt!y*FqbSd%MjMA;FP3iaDzZ&0)ez6YEYFrSdKJ280<-L zp>0h%4ZEh%*5&ef|NYO;;a&vc)8%>J$J%=?RQp(Ystg8&h>o@MQnZ^+=iz>=)8!i3 zZ`xvZ9v0U9vR`?gn@$`9%fhi`;_&wV?)32Eci(lgqN=Sn%WZ6;Eh)zuGnX9HX@C6} zzd0R`FCX5&JarRymuV(@*-!Vc%TcHm$vsK;%Z+sozg`Q>(d>FfTouj^6o-`s!m z^!%sS-+VLQ(X8Km`SkPn{@>{MtA2g#x39nY)!+G-+t<&3c=PZ7;&}g?PoMt~ay!qj z`!JRaVX(jX^|*n#2Z z$`j>YIA}OC@#s`|na_5)hTTj!m)1AhV>QgiI~%9woAbkg_xoCZb<#Jl^nRj;h2Kv3 zcA_KWgghNcg?Tw!&j0o&jDpL~RaL>buV?&+TM@qrIbAfI*3XZXXCEAhc5-5yFonXxA zD3r<&NgBbTwK!|sEDJb->*AoyNS=gN^qttl=1?uAwiK!9^Bv^s*J&2NIjA$ zf^|w?Sr1eKnGzUUB|B+>7Kuom&G^T9fV0Lh_H0$C=^PBUsTI+xf>OY35p90kP-kZ<5{Btz-mIV*E~{sN#_iU*cKT?iB4Z7jtjoTSB+1goc8QT2w(LP1L3O=dq)g1lL2Ebi@XX{~*XM}l9Bz)0 z@;|)#53Hqx=^`wWx7}=;mm^WNb#<-@cjMAT*}x(PR;{8e6v|R^GZ`ZoOnn%8#5VT* zmOZm+Jb$IuN-J9E;8ABVWznN>NM%_TR!RqRNo}OWegkWE1Vqzaz+JKuF(IPw6RpH{ zp(Vst!??1fknphSjK7IMRZl(vV2imWiW%HXgD$+RBCR&tn+eRqy7>@0DI7+57 zv$UWX$kY6Ad3+9R=lj>O=AixV^=Ur68=pVEJYQICZbzc*o|UT$o!=d$9NR2z{qCD@ zSmp7DANuP1^P|=(UOC6Z+uw3_ZpvgVg(>!RMVqfLpRQLk>vmJ$u6f8`{`LO=+Zv6- z!*clcZ~XD|PamGRWAkyCivVxl{rk)NpI@GT_i*>>e){eAfB4UVcsT#%^Ovvd?ely* zJpB5%8hw3!U*Eo7zpj7yr~lb*o3=Bq7e9>UaK8Nb_4@o+Qr0a@la=Z`8Cof=dv~Qu z6UbwaNZBq=+d5RS8<@my8#3E`m}=a~p{cz(%}d!|rJX63Iqr+x!_MT(RAw%YPQjCK zt#v9~Yi&yP{$3)oObfhJHmU5%3Nhmlq%w$!KuY0}4t7}`T7|-L(hP4@kS+qmPC>6$*e>mN=|^; zJqekP6c928lLsP5o-TIz-49=H7rmQd!Bw3~nIwEfA5vz-fbU!?c@ap_YwAPTwV{MX zs%AT|Ckho&;(|zb92Sk#TCc<+jkzbML7koc|Lx(~mSx#>CT9M#S`Ydj|emY z5G0e*P*SO^8`VYCBj}auu5L7jn!FI1A|ZePqVouMGdHty&fcq;a~A43#P17Ax|>EI(+q1-6eI}bNkNU_e-)E` z<{2AHoqfWOd%r$?*uVe&c5{QSdPtu?UM(|g)xfZ(^-RQvGo@esDxDAe%QM}~3DLct zs)2%dsYRCxC2ZX!L!5-G7DeUcbECYbhrju|@$&rq{M3fCvyuBYRT9k!74)$X>#>$x z$9#GD{^uTkF=NV(nJWV%)m7h({j($8zj<#y_059>{q)_3ZQE-p(-39e9q`rrf4Dw= zSnk*QaIATK{r+Sxx|FPKJ5C8VRpB}zC9=>>a{wXi( z=@(xvF1Me5&~sYS`|tnd+wZ>nV=Z(({dONuWx2n$$GuO{K3tr#7^s#~4!)LUeUl&V znHH{h;bV@C6FF&w8Ca62S>^G-bX?0Rx6`U`*Y!AW_e*|zPE4f7CD|0x941GBteLnh zWj)liEX*W21YXs6Q6f^?EjmNoN!VsO!8fZ}jXZ;RGG`htH6oq8UtrEj5KU)_nC>oa zB$+4E%FGfe@t6b_7=l?3L`Y$wz+7m1j#MHR_RVXJPLxs{D$-r_9aJS!kfA%xJ+u(^ z&^K&1%wZz}J&tdw?~W5hslP&3Fqsbu8nMGqG+vOz(}Be>!emC&kRe1Q2rigD9lQ_8 z3F?s+SQFvs4&Q?k;=n$^>Hu<>vif8KRN;+?i8FCHD)|gE0GbpO?gVmnUoUxW|lgGLY#i}_@TYG%wyG0dGLyN#3= zqZD*2c^#TKo`a7-vo?{`lvOmBCE6_=zv6LYwy>mpOGVM*z7lz;jRb2**==-CmQI8= zBV;s$kqvIcW9}qHm6#33lGw#m7cQq0^DOS(LRR*Y#HH=F-^Qd2id1r94pFY9WMURS zl(MR`*kv2n%`94bOy~D|*9`BQ>p?hrF14HV(U63Yd>_lXCSB^8@^VOprFFWyV+*q# zHAhaFWwy)g@ZMY7kPg@$TMM5&`tBB8Es^wn8a5eZ+-ypwAcGo^V@!4;kFlKJGD!Z1 z)9;wLBpZ^%ZM)5~9Kxq+qI4e|(CmGt7^4#p9pgVjUD5)qvP?X{_=TT zw|@CBt}mzuAA&J*sSB_k@^QVdbzRQ&lu9n=W8w;|r$yFEQmYUzRqJ{<6fMqXc|Dvf z9h9VwGJ(2eAH+;V=nbwR%xov<)f8+$o6JDKCftE#bgy zh!ay2meELkqny|;6j|)q`A){h@W2W;_Z!M091$*~6K4Z)fah+xO5y<6jgZL#DKHEY z)H|s-FEYd2NSsML-^=#unt4u$Q*_cZ6w!P1!CZ-_TZjiz;TWVuh!BDke4u2+O11|m zvXBrcI3H<_z@*CX5kLgd^hhhljX1G*&|QdufJovF0%>9wQh+ErLPU}=Qow=`l0hLs z;Q$11L^BO+KU*|hbZmt#^QRnKJYX3TRm z1M6rFI%VuHSBJNkodv_(V$QB}4vVQ$U24iS!>rSw?8!)6O!wO+|Bqk%4HpoU%tVV6 z2}FQcmC?vCOasn+>ROrQ@Nm?nYL$|-q{vAL1a>k-40G|;VvDv-y1dBV-1C}9-42C{ zBGtfp&N3sf&`BwibhwZZcv2MdmS`b#NP_Mn!ftM6#MGw|!S{*d?DqNN?JwVLpY}c* zCk^$q+uk)r>r3Sk*VFN<*XzeTBOq;V4%Cvjr>9`yOv-|BBg!?E_V~HKK2ti^huj{o zW+5tbZ(NJfka<0vzPvttZ06aLp-s-b=5WZIM9R4z&Tp2}{ZD`V^V8!e(c|PfyPIT* zo{`>s{dKNOd!9dk{NZ$eTn{zaHLat!*OwRDCbG04V_px1zxvJJEkNV#_|?~R>-+QL zTs|gUq09C1bbk0UjR;4Pw*2C&wR}DH z>vsEm$ol-#cWXWMdAr^A{(3WGpEnj6zP95iH0HHd#;9X^STeIf--K*U|bcDQ>kp=8L+jn;GY*Fc4EpAHd%8Juz= zQN&Dd`2(r{(~)FTcMj&=5FLkSO3F4-nLdl-%8nkwAYnh$W=kl-Cd6{rIQb zK3`>86XN5N*?B2s*SAb=eeYuq_jYMM8s*eKH=-#axIW3@fH6tSzF(HZYAGaC zvaYMs@u3t-JP+^R6Dj$SebR^!CMv|y z`^*W^x7oY1&T%Cll*?>GNaR1(Z+yhzbav~Kjz~nzWWz}*iw8hy&Yq4rol?@}aFV(f z%}dR$N;$82Ny3#22UXw(N^!Y~)ER2l>AL3}B_^LwtL#+Qq#>n{3fGi~h=rDb)i6L5 zUp@K+cb5bUrF<{H9x_-st&I4;hDa%**k(kEwbTdy0Ck`QcS<>OW+P)usVv?%YVB%4!)NFSp2`DS)iNaV`mCQ?B*448M36w@i z1t^al?h#O-PCc7Y-T+lxNRJ#lt&4<2gmQ3Vk)$y_x+G!hu{#ryM|5x|X5}#zB5-LGTNo#uJtbraAFxP)l<0AmtV$kSQdD-a+J0!JZq$|;a3!o=AD%7j4y5rZdU zkb6iYQS|_2nhhxnPn({-PqBoP^9U{KpvmOJEGcWCfB-_kDHJR&1j;VNK0!bbXapt9 z!J>o-&H;iCL^z0SxCew;5k43Y4v%g`mrwokKmFl)>mtsz(iobEpiCsui3^jfBvNG} zV#tzaFoZ{|WUnHb7fn;JCY?l*2s5SWW2HJuP!_CV?#kiHlmjCLNL9$%oNhA~8e5dY zGdK)OWrYhTuxbP-*Q81*O|c@(DGY4}hj2_|pVMr_bgr3*f>9`q8U9UN@-Oe!E6LdtOPJHeTMbk zK~pn`a=*2(*)F%)_7;;#wyV+f76KmD_Crap9Ob%SCoz0>lSRUuXBzv?W0(K_;cvk# za|BOW4uolam+;`yZ@W9fgAg@XOI?!XH;1|&(h>D^&b5@PB9t*Xl_aK0#4$Sec9}2F zc->|0N%^qkbF`FI(@AR*glL51ge^1!!a$G{HCYyn8-oV@uAeL_h0{x#`x(k z-%ppm?>0a}>e;LvWjVe(%6b-Ep1=F>`ugGi-MiEKcLdjTw(HAn++>O%c&*EnX0La5 zUr}7r`N868|GY12dcAC89|)Qw>YH5Gk_Bx(-GBXcio@;ak1v;fYcDC2ZLdoy!9ux3 z^Vs~;<3H`T-EL;HzkYtH$GiUWJSpYEQqO*UO3R(QIRZ|qH7zwcp5UtZoJZ8Y6ohdlCqr zS#a3s8nzRXII&Wx>r|&9l*&|^qu=Jhq`B`Q>9*hIo~iOlmh`Y?&9f%}}~Kb?O;VZ|^qGz| ztqH8QSq~%PFjHBJ!21=crn;*5wqF5Bl#`4(L5Uy`7K=$OHgrDn`R=}^yXVgzY@c92 z>9n5az8$I_zxv|go4;e5j~{+o9`0VB=lV8F+=pJdr@Y|dH@|{=J|15F^uzXiEeqcK z&EH{6ssp{eKK+E6AZ6V4IWMQ*{W^W~4!2iUkiGr!FaMnNz6M@yw^&u3i;+-Yarboj z?#(yvPhb3oxBmF}VQb#o6@An-Z_ig7E_v4TSDDYB{`BXkr^oiPzw9q1Wpds6HDN8K zp(A{hQv3Bey}4KRxV{qgiX_5LNWF#Quux8X_omcZjv9HXiSt^iFcwEXABZejQ>du0 zO_DV%NQc8jubE%1S0u#m&F1a)?rrOJGsDPwjpC?8m7 z%;v7(5M`6ZSdBIaGchg7@c63mHFymW@ErNA@NQhlGW&o{By|#kfthWFO-6u| z`h<#kFe{A~01+D!V}vr+6ZeZnaCC}8VDjuViFpdS>yc)IcVkI0;KL1&OxPnAu)`=4 zBQPQ)z$j_{Zy znE<$fgG_=w2t-W6ZcY@CObm)i90A>d*S~!H>4%Tzq_x%}b7Cs#=}VqB%+Q*%1|&l)3yr|EKwH{|uJ! zzk>HZdh?0x`I*#hsH5HX4nE#S^P(O^b3$N5A*Ab(W=|2lY6;`493thk#^~YlpV!}! zGpGe>%n{SwEudwUFhK>Zm`%=US@QXAt;hWE{&+au9STcAO^Ij#LPCU{IeXlI6!U7I zw|IJtG13=b=j(OB%qgfQ%4gOgy1Ir)1_i@RNMf)EYj_{R0UwboW=htagp7TXy`sG? z-~Lo~Ds3jFwfTUPtP-SQEgWv({Tj3QenIn+Q=bi^ciYy(8yik$%yW=xLRk;t4PLg{ zc^Gr8ML0=V07AjzI@?6b9(DiX&2Jw+e!Gon9&nob4qcW*eEqloc>KlN{`uqn^QWiB z&)0oOaxw8FWud$K^Vh%q8;c?N&E?Pkx_4{Q&+i_Vhp)m%&F9v(i@h#=^hQOoEGKL~ zm+~$ym-^LjUw{1581sC*yY<_4-JRxc<5cqT?qPp?`F#EMm;dTy1To-j+>8|m%;E<*0fMimL)T*&Y6i=3uCAhom--) zl}~SK@>o*jl`Gk4$>5ivq%mn2(>ww?BXDBs15jZQgLP-z=?%HX8Aqb1(OLe9cn&QFaw5powTr$*o+8f z2Q(Ea)o(#bGGGbZ%CQF zMIl5Eb{ajn@SGtfz{1nDip(&FfK5e=4B$e+gan$D5U!|&%tcrD1QJL=3FC$mJZD5O zMFeyXD1rh65-^lP5QCH;!65)M2a!Z{VhI*l1aWXkhf2aSlJ(}>py3<;m)&G)vo-5s+BbVQr4 z#05mY-&9kuwd;i=5vAzEm1TBG^Ub0sN%G&Geq)4GaxH?yqfdvi6p9*Xeqn~gbQ7aN-u7Uz14@4`GiyV7Ij4!`CPvED)0MG zA1)rQEK#6Zj}P^$U;VPae|!1E?_WN>w*5ImOH$6BDUa9ZnwNLK{c>JfesjA0@Tc&T zP+yPf?yE0_#z?YE|NPyzdwa3TTN|H0f85;`FYB9_9Q>?*_{0BlynjzpwwEWkkg&#h z`|e!$;pz3~lwMA6f1P%J{prW+MwzZly1)DS&GzYeIN&ip$xcLEi8f*j6!=6D=!vjHDrE59Nl%Colz^#picHQ0lVVPSvM@PCO@vJX;oxwP zNCenpc|-e+l-Y00g_uFjj0xhHv@AATL?P;s3Ju64VaCaQ@|2JTBBbIL9Dl_EiJXLq zR4F{>By!Rc)*wg1PT^nyb%YQzaRU-zNXbE##lx9E5l-RTt$g^Gf1Rn&42~Iq0+Je| z7?rW_FSotl_+q!hj{459A+pcLs@`|bYbqq7U{#gyUXTQizEQvwqDttIn8!_79WbPb zDVk~9q=?;I!jxbX*=a!Q!jv>;(VUXcNg^J7AfVGHMA&BQnbc**Bo&1w8hVm3okBFZ z5)n+7eY{R1XVCO9djeTmq_sI|JuJ8VhTdi=l&!92n0Q)W>cp$IE3;n)~&Y@|m#FB8&n|^k$&Ml8Pim2o!mR z9M^t2e<}aN={F1{GP5Q_`W!SfICxHif(C?b^OWNJ?ywxo;k4d=^QJB$K1qT&5rQ#| zMQswzAjGzh-n!BF=|i-9EFt5vP%3G2salw`l6Do2Bt%nPZ4McUuoItxW?%-j7+pxr zJ8W2U(jpYe1QvZ}$Ev0GOMqshH2R!_TWg$=mc#q|a%;4=%i(yQy|JEdd)K9`w2bju zAAXtdbner8!<1a));+ITDi>aJF8k#sx!1d|;; zLprYT8T)82&!2w225o^QyGS$VvEIE2h0@`>Z-4009}Z{Z99y@P3H!t0NWh%w_3=~6 zeE#}xb+^x-ehP}b9^ao&Pd`7N-rai+rY}GK+yDAv*SotfzWDMtLUUc^^T+SHlvLa< zVPQ-YL?Yq+lKHT3r2TeSaw_Az9G65Vjk}U`V$q3#bu9vqC9`CPJ51+v%`&eN!7R+g z1j=iKt42shYXp^Cc<#`}$wZSIF&Tz93^XJy&ZNCznh7VbBs_KPBWG3z6N!NEp z#1N_kkgLapFi6RR2qX+BiAWd$6y3#G(rtTv{{7RB-~AjZu|yH>&RQXN56qs>^6{vP zq%0zpZ1#>MO5~KXkJ3!};q$zYc`-DNV9%^3;Jp%knrAWB?IFd{PLAY>As&lb{qa72uo zv270J10e*Hxo8!}OjM-4e;2m%HhI-GB}iWUbv-}SyMsv5q{!za@DLFr7+K#VdG8)Q zwA#(~{R$y(W8bbb$@TeV7{bS}PAdJnlSvh&^}rZ?7^B$ecIi9&x~?F`x;+V=bBt_(KisEJQAUQg z`?u+Em}@OaF=rQX8pi8l(`@+b<#XR|TJFq7eRyZMm7+5&->KG|zg{V3Qpt5?m`$ma z{4(%7glx`E#M*U#`gp2`K=`yi7w^yMtNSm$ev{$CW%h}FV@hRR{r2fLXzw>+aqaN# zmnUT^Eam=`7?PJc(6&agosRF~(trBXpWF3QJ}&v~7pqp*AY-x_%5HLddEFkbetWKO zzWU9t{^9ZI_rLt+-RbOCo3|&_ z`}@=J^7K4kpG!&azW7h=`=5w!Z-2FX^WXgE1^xb<*xQVyd+DFF_0CvtE#>mk_<0dX>L zazgBbyfF#eKp;wjg_+EhLx!t*I*GV13;D(x?xOzclDO|A!PghKLr7-#nmjKakl_R- zzl3H=CQ_-tnu_})`>^E=VZ%m2Jh!`kzQ|=q_O z$b=wbq3pVdbnb(vWAqIX&1Tyv5+^0Nu4g&Gi6;3g^fGVTlsRH-OkpBRPAqz2ES!5% zo$DIEJXsKZ_?)g|y;~0DoD^$DJ-#n`(AINVwJwz02qKPrFp(xnVvfE6h0XWTDKBlG zW3sFCjb@00df(Y(jEyKt%r*vHexBX6I{oIGTr*WU9hNsK-LI5|3Ub;Wk(vpRV%gPZXqS-xz{N&UqnENmWkk~-MiNToJv z>)}n9QJVMXJGam(oa*6txb3ePYI7u>ZyxUAaXJ*?UC6Wi`ftB}^UZ(w^e_Kqf4pi* zbC6vumJEqp-=xLfzx!gnPlS~c{o%j-lSq0vpW9B?_Gx>5`tomnJ1G#S{_)4l7@kp< z^V}P8fB5nj^$_X)T-~LsSI_HLc8PpC6t?w?V=jvtZSB(gmXIj17>mT>o;YQA;dwX|6F zVRjwnIjKcZAsY~5rVtnP&^sQ_l$GY7_8M{!3WF0DwwsH}oZ^G%$aaHNmr5QIgR?R* zb@K%7PTk!?(cr4Wl7%fau0E5Y_9F=RPgC7V;bt2qGl}xjN7h zK{>;3FgCDJbz!M2o~T0M5x{K}y6yZI^Y08-!hy8qYy{{ld14<%1%y*;gcy5 z141jwjc^aT_ymy?mxvs!;2=&As9&3ff?+!+B1r_|K(Ii9oQVu!0VX(siBfoXh6jcD z$M2sW|NLE)gD+{jJ}t*%#Nd#4e4YJO&Udm8D?$_28l^9=w{wY zZ$sQ;BxAYvXb2!Dh>I^_?Y4`@Y)IU822G!OI0$u;5|=>_OQq7bUD^G%W7}w{k|;dj zJ(p4rIVa7PWz`}cS}CyxyhmV;wj0zwe?~41ux;CKJ#3C?F8%g&nVZk(`))L;&6_nO zH&@W~nAO#N!y&oPebw})u4(a8UTYqQW0qXyKc0ULqLg*IXU-fpO=QuMmvOm-5~orU zl++-U#sa=C0dSQ8gTkxu0x;=C?k zqAaQe5OZ?92C6HBod5)pCInFuZjL1Am~-?~*yZ&6?YFl}x=DNb*!QV_`S!`pW=xrE znK8rNSh&xfqtt_EU2OW^+PnYoH}>IY3P89pQ^WS@QIAVa#oD!KfzR{#&GB&D#^vt( zuwS0iatty{l(L}H{_zJ{mqlwIZNGLo;upXA-QoW9@%R6=-94hfuO zEjmWm{Py?%>;Fs|?|${`vA4|U*N@+wzxl=S-CMMt2Y>wZ(Wlw#O^)~Lp&s76|Kc}) zfBXLT=imG;y|$OzcxgYc$FyiA50M!C>HO}?bvZu$e7V{7^7y0Pf7L#J+-@zRt%tjM zxD&JGu1Gn3_lN((XYS-n!QI<)TE9%Yf8JhOds(>vq2WcDe4dy!XTi)7CF2kvj!ZnJ z<-`F|%wVG_ng?ql>s$}SNolZDVdrj?Q>+X1S5JvC$N`T?Br!1&Du}_!1Br}CJZ9z? z9xdpBc@OVV7dB#SlF#hs*dq!#lQ?*BWha8|%&K$36n>^ZW&qaqI*kO(?{63w_J; zMwlR>#E1X|u@ZaW4SNfAm{O=yBqYm+v|n8+L5ahOD1;dXFo98mFKPsx?Bq*g8_Wr@ zlN1nW+c2{7HR?UjtA)^Th=yNXl8za0Ch<&|%uyl689to*9;Z7WS5^jF>!+{i1BaBFWPImTY@JdNE*exL$^tn#Du{_z$7Fh2M;Ih z&-3Na-~RmhT9j3t+~5@4Wx$zm85%nyJg);rP*I1oibtw|Yu}wLg+xjbV-*-u7EiOM z6e%xo`0a|!n4vxd28X+)!j$U5mdJ{5GA!X)`H&idNtvco(lNsf2#kRnExlaq%uB!QI^22uVFGuG_F_j<(%qYx6eD=MI;89^Tv5!<|&i-5Cg_JQ8L0 zdUwpdqt9B(np_B{cgNL-j^I?}KR^5jk+kg&o1`fy!krmzuC??w$;F(V{r*@EB|W@9 zFAon4aYs0DUdSEZJ=_2u9mLaYbni&7KYqS_zVh-=ur0H#>ymXz;>ec5kq)FLi9L*r zoK?9I-$MxeO}SsT$KAA-W2r0Uvbgd7`1AE*ee5-_M=g4cFMs#<vzyBa8x7*fk zAM3;0rQY|=lJ@1852w@R<=VAgpT5gwxm}ypWxGDF=Oo?7>j!Y1`}X+h$JMHhPxb9r z^>{hI{q12n>>nR{drg^{tISrDp6^o4v@Uw8!oGLf}Z z#_&A)EK9m>e7b{e({dqaS`i2WEe{-%lVU9x5bnlDkOw@>5bjQ*3Dk&4s-m3OCUYPH zlmMr`8)eQB-X#>#QP$`;ghwW>*}po3J4~$ij4iFm%!k zW0{GWQrOP5xQ73_l~ z6VKp<+@KC#krRalJCOsOng>CG4U-(~GcZ91$N);vq>#u5HIJC&3!ESxMudoAkc@r> zNM*NDR3DrXRS%jH8-qv$!`x?L?vZtDiDTYQmWoIM>b#td7Dl# zr*F2~Ya4SLTK1RM+tqvbacyQJlVD6)7t!MT4M>x%i1^-ZIIEVz^>kXQ*L69xYi5a5 zs5SX->Mw0tl1a3Hz&${4c;Pb4SyNK3aYdnX&DTrY4H47Y7M3;j<#5g=`y96kic!}3=JeL~ z>#dFR`+FN#H!U33eP5R2gq2)m(ssEl@6P?@iI|h#-(IhCj+{ttn5CYMZ*0WPUf+H7 z@SFefKlAJJU;ej$db#X+Jo()B;ZyAG-7g|ueUIhsa`($G!O26v{ilB!-0s&?Io5f* zfb!?3&o*8aksiKaEdBNAHX1p!rh15nZ+@LcjLG)#^H1MJ>;0wQZuGkSRG_T1EHx*K z;c%VTOWSQZyuIw7N3%XJ=+Um1TZ{6hCcbwIC(7h=zb*H7P%wHV3WY!8%K#c7t#f z<+0NwE<`qAtTbKkXbge@iG-O`L`xKuGPRBOeH11Ok_FL-K^9;}Hx5R^>>M5-h%@rR zK{Pw0kizZ2v%6nHlg=T6;DCt~CT|KN+nELdVS}wxgpQrk$}tfa0#jG@7MTJBAu8eq z%EeP=+kg%^dVqoG!-XiqG(#p)a&z+FWwjk(W;f6GgyB+yRP4%}ff*hWGd$t1W)GYY zgDWsCbR}WrmAq4L!6&9GxmmgkyDBll!rZw4N>#|!oh1um5)zFKD!>xVutduO4+;xe zM3h*7#tb)i7j-~|Kn7Lu@SRX2CdG7SU`k%doPvl2h9D&=6ye@T5~rZqNeBpshX@lR zn3OQ#kT4UGfPy<~CNeO5#`B+kdVR6oMKV&Lka=E$HDRcVyU%Tdh`nwmxp2fHA}5|N zbi7Yy4n#!Xx3m=2r4~stj|eT5+LV2l#6FNJ!$n}6M1_+30xn$H2Yi4)Ja%Q9ZiF$T&&*+? zy}T+C0drWNb8eTufnu5gOcqR%KqCU~Luq;d77nOW9|O0GCQZ2IL&}9on5hTDsRn@@ zJQqR>Dw+z|IfrR6YQaYmV(~C?Qi{Q`O&yup?~9l9$M61h*(Rs7f4au#Ghsa*`Y`5{ zrYnlb9Wsb&Dkh|&G4|m$yw5Daz+g~ z9N~*I>#)Fb{Nl~&-TnJ-zFAM_{?osCkC<&Y z+sE_e=e(QKSk@d@dH%QCPk;Kak^K1n{M9#q|L}ILr#H9PSKIs8qki$#<@>+bHfHn7 zzVT6Wl^M&++#%!j@#b{={OS9$l;hoLJp$g|eeq=#z{Li?T=qHl?e(dAeaHLd>Er+P zdfA^o{PE>4PtSk+_VSni&zoPo`GaQuDFO$Th6=>r>7$DUpG!^QkD$ zAmV=EHVGNvPJmo(pBBp4M>_h9o$^%Gpd^%nQn)ZlQugV_x=2X2)(~ydkqu_u%fhNN zBw8cRR;um|f$#~yuY*X{26!O~SWp#-P4&pqqwPGLY;xOZZ|qM>O?{(2*_mRel#w-b zH7kYy9gKuHVX#9SaL+!>=}1=OHVM0V+8v(G&|piOaZ}eu58fAO8bm~ zXdUws1Zta{lygqvY>$Y_c1`{2D9%CnEAi>EO3=dxb|PZZaAeSxLMa=`?)eB- zwihaA2!{>eMAJzC2WJu`#1>LRhS519MRke^y`sI6HZMoy4B8O4@R(Q)lWFxp%z;Sk z&BydX6bg%o&ZBYMg--&Qle?J!Ja|4vbeJRD+K7+{32T6m3E9pe1QJQC#F}UhhQX6h zzzIQ`WWE3D%j3JdyRX(a@6+M#<}xjDpG>nOLdYV`+tf-+O>P^u;nFRw{qbdv=37e% z2N8-?o^m%{L*)e+fV#hF}0E!?L~Q;Drvr#U{47W?jfyA0QB-`dqJXpb>^XI);~ZcM}6 z=ddwEl5O3BXc*6t*Tmj5Ntw{(Rao7KIa91*>}sy2Nl_Fb44;&Ra`^O+U^lzb@cw$E zx%uQVT5m5TE#RO@@R;n}g3TrXv&4>9cl7qOU)LsS)1$+~GkiBs>Oyg20k(@zcT;ZS zR6+uNv8e@-QWEEwA=UJe!C&G)HZIEqny?VfBE6l=FWu(==N-`G&$v*}&GV`M45!2-uK`-BQkJAxnu6dTo)&cDF1hX@-w*?mXJ+ zF=r=c*6^jk5G>Qi927H}u|!PB7Ttp)1}vaQ$8z92qpDDf?S*1E5J;fO&Im$iz-$(h zIc15gRt1s*EWwdv3OgAm3Hqx-ArzwK!3#+u$}_9!nP&G5v3*1-Ab^}aB7`YI!Ci?A z7-So9rkp?p(ZEai200K&d!x~43Otb+?;S{yj_eVmV;i14JO?ssNwm9V#E893AvX?O z;Av(61hcRa{uM|eR#L?-93Qp0Y} z6{y@n zYh@Wtb6yE5Q8XAKT8N3ramqxT6=5!r@Xo{>ZSEMQjApa@&3wCVP2u3{)~(Y%;zEA? zbnCOb+176`pvK%t@2ETems3kFWdd*nB#cB*}!~hDkBHZ(Wkogh38@t<~2zcc;@k&C7as zzPmrJhr>Z|C@S!5W06#k%=mZz?%(~pfA@b&|36`9$wH+@6*vF@002ovPDHLkV1m8_ B Date: Wed, 5 Dec 2012 00:22:39 -0500 Subject: [PATCH 135/527] Correct pickling/unpickling of dynamic specs Previously, __reduce__ was returning a reduction of the class, not the instance. --- imagekit/specs/__init__.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index b884eac5..c839aff3 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -143,15 +143,22 @@ def generate(self): return content -class DynamicSpec(ImageSpec): - def __reduce__(self): - return (create_spec_class, (self._spec_attrs,)) +def create_spec_class(class_attrs): + cls = type('Spec', (DynamicSpec,), class_attrs) + cls._spec_attrs = class_attrs + return cls -def create_spec_class(spec_attrs): - cls = type('Spec', (DynamicSpec,), spec_attrs) - cls._spec_attrs = spec_attrs - return cls +def create_spec(class_attrs, kwargs): + cls = create_spec_class(class_attrs) + return cls(**kwargs) + + +class DynamicSpec(ImageSpec): + def __reduce__(self): + kwargs = dict(self.kwargs) + kwargs['source_file'] = self.source_file + return (create_spec, (self._spec_attrs, kwargs)) class SpecHost(object): @@ -169,7 +176,6 @@ def __init__(self, spec=None, spec_id=None, **kwargs): raise TypeError('You can provide either an image spec or' ' arguments for the ImageSpec constructor, but not both.') else: - # spec = type('Spec', (ImageSpec,), spec_attrs) # TODO: Base class name on spec id? spec = create_spec_class(spec_attrs) self._original_spec = spec From 7578903307470fdf5dbac9ff3f3cda7cf4fbdcd4 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Dec 2012 00:44:16 -0500 Subject: [PATCH 136/527] Fix test --- tests/test_serialization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 76d53912..cd7b6d72 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -10,4 +10,4 @@ def test_imagespecfield(): instance = create_photo('pickletest2.jpg') thumbnail = pickleback(instance.thumbnail) - thumbnail.source_file + thumbnail.generate() From 2a6199b8040332d8727006a8bbbdc2dc96e6fa2e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Dec 2012 23:16:07 -0500 Subject: [PATCH 137/527] Simplify get_hash implementation --- imagekit/specs/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index c839aff3..9db70d03 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -102,14 +102,14 @@ def get_filename(self): '%s%s' % (hash, ext)) def get_hash(self): - return md5(''.join([ - self.source_file.name, - pickle.dumps(self.kwargs), - pickle.dumps(self.processors), - str(self.format), - pickle.dumps(self.options), - str(self.autoconvert), - ]).encode('utf-8')).hexdigest() + return md5(pickle.dumps([ + self.source_file, + self.kwargs, + self.processors, + self.format, + self.options, + self.autoconvert, + ])).hexdigest() def generate(self): # TODO: Move into a generator base class From c45876f95c2c5e2343966c2b1eb7d90ccaaa6372 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Dec 2012 23:16:34 -0500 Subject: [PATCH 138/527] Ignore some style errors --- imagekit/templatetags/compat.py | 1 + tests/test_generateimage_tag.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/templatetags/compat.py b/imagekit/templatetags/compat.py index 8334dec2..f26e8b87 100644 --- a/imagekit/templatetags/compat.py +++ b/imagekit/templatetags/compat.py @@ -1,3 +1,4 @@ +# flake8: noqa """ This module contains code from django.template.base (sha 90d3af380e8efec0301dd91600c6686232de3943). Bundling this code allows us to diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 82cb3ce8..95face71 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,7 +1,7 @@ from bs4 import BeautifulSoup from django.template import Context, Template, TemplateSyntaxError from nose.tools import eq_, assert_not_in, raises, assert_not_equal -from . import imagespecs +from . import imagespecs # noqa from .utils import get_image_file From 042bdcefb61e47ebb37897c64ffd86d47f43a3fd Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Dec 2012 23:38:10 -0500 Subject: [PATCH 139/527] Simplify dynamic spec definitions Use a closure instead of an attribute to store the class attrs. --- imagekit/specs/__init__.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 9db70d03..df99721a 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -144,9 +144,14 @@ def generate(self): def create_spec_class(class_attrs): - cls = type('Spec', (DynamicSpec,), class_attrs) - cls._spec_attrs = class_attrs - return cls + + class DynamicSpecBase(ImageSpec): + def __reduce__(self): + kwargs = dict(self.kwargs) + kwargs['source_file'] = self.source_file + return (create_spec, (class_attrs, kwargs)) + + return type('DynamicSpec', (DynamicSpecBase,), class_attrs) def create_spec(class_attrs, kwargs): @@ -154,13 +159,6 @@ def create_spec(class_attrs, kwargs): return cls(**kwargs) -class DynamicSpec(ImageSpec): - def __reduce__(self): - kwargs = dict(self.kwargs) - kwargs['source_file'] = self.source_file - return (create_spec, (self._spec_attrs, kwargs)) - - class SpecHost(object): """ An object that ostensibly has a spec attribute but really delegates to the From 12307c97aaf9e46b152366d7253ea7fd9743b2fa Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 5 Dec 2012 23:51:30 -0500 Subject: [PATCH 140/527] Use state--not constructor args--to recreate dynamic specs Previously, we were relying on `__init__`'s arguments to recreate specs. Now we do it the proper way, using the dict returned by `__getstate__` (which may or may not include those arguments). --- imagekit/specs/__init__.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index df99721a..908ecbab 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -147,16 +147,27 @@ def create_spec_class(class_attrs): class DynamicSpecBase(ImageSpec): def __reduce__(self): - kwargs = dict(self.kwargs) - kwargs['source_file'] = self.source_file - return (create_spec, (class_attrs, kwargs)) + try: + getstate = self.__getstate__ + except AttributeError: + state = self.__dict__ + else: + state = getstate() + return (create_spec, (class_attrs, state)) return type('DynamicSpec', (DynamicSpecBase,), class_attrs) -def create_spec(class_attrs, kwargs): +def create_spec(class_attrs, state): cls = create_spec_class(class_attrs) - return cls(**kwargs) + instance = cls.__new__(cls) # Create an instance without calling the __init__ (which may have required args). + try: + setstate = instance.__setstate__ + except AttributeError: + instance.__dict__ = state + else: + setstate(state) + return instance class SpecHost(object): From 8c80ba3b4f703a3be5c209593bd28a93ae928598 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 6 Dec 2012 19:54:26 -0500 Subject: [PATCH 141/527] GeneratedImageCacheFile stores file manipulation attributes Everything for dealing with files should be part of GeneratedImageCacheFile--not the generator. The fact that GeneratedImageCacheFile can get this information (storage, filename, etc.) is a convenience so that the user only has to define one class (the generator) to fully specify their functionality, but handling the cache file is not part of the core responsibility of the generator. This is also the reason for the renaming of `get_filename` and `storage` to `cache_file_name` and `cache_file_storage`: the generator is just as useful for those who want to generate persistent files. But the original attribute names didn't indicate that they were used only for cache files. The new ones do, and don't preclude the addition of other versions that would be used by another `File` subclass for specifying file names or storage classes. --- imagekit/files.py | 34 +++++++++++++++--------------- imagekit/models/fields/__init__.py | 5 +++-- imagekit/specs/__init__.py | 7 +++--- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 52836dec..9916c2ca 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -79,39 +79,39 @@ class GeneratedImageCacheFile(BaseIKFile, ImageFile): it. """ - def __init__(self, generator, name=None): + def __init__(self, generator, name=None, storage=None, image_cache_backend=None): """ :param generator: The object responsible for generating a new image. + :param name: The filename + :param storage: A Django storage object that will be used to save the + file. + :param image_cache_backend: The object responsible for managing the + state of the cache file. """ - self._name = name self.generator = generator - storage = getattr(generator, 'storage', None) - if not storage: - storage = get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, - 'file storage backend') - super(GeneratedImageCacheFile, self).__init__(storage=storage) - - def _get_name(self): - return self._name or self.generator.get_filename() - def _set_name(self, value): - self._name = value + self.name = name or getattr(generator, 'cache_file_name', None) + storage = storage or getattr(generator, 'cache_file_storage', + None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend') + self.image_cache_backend = image_cache_backend or getattr(generator, + 'image_cache_backend', None) - name = property(_get_name, _set_name) + super(GeneratedImageCacheFile, self).__init__(storage=storage) def _require_file(self): before_access.send(sender=self, generator=self.generator, file=self) return super(GeneratedImageCacheFile, self)._require_file() def clear(self): - return self.generator.image_cache_backend.clear(self) + return self.image_cache_backend.clear(self) def invalidate(self): - return self.generator.image_cache_backend.invalidate(self) + return self.image_cache_backend.invalidate(self) def validate(self): - return self.generator.image_cache_backend.validate(self) + return self.image_cache_backend.validate(self) def generate(self): # Generate the file @@ -127,7 +127,7 @@ def generate(self): ' race condition in the image cache backend %s. The' ' saved file will not be used.' % (self.storage, self.name, actual_name, - self.generator.image_cache_backend)) + self.image_cache_backend)) class IKContentFile(ContentFile): diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 6b3287c0..131ff332 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -26,12 +26,13 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, - source=None, storage=None, autoconvert=None, + source=None, cache_file_storage=None, autoconvert=None, image_cache_backend=None, image_cache_strategy=None, spec=None, id=None): SpecHost.__init__(self, processors=processors, format=format, - options=options, storage=storage, autoconvert=autoconvert, + options=options, cache_file_storage=cache_file_storage, + autoconvert=autoconvert, image_cache_backend=image_cache_backend, image_cache_strategy=image_cache_strategy, spec=spec, spec_id=id) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 908ecbab..fdf20444 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -19,8 +19,8 @@ class BaseImageSpec(object): """ - storage = None - """A Django storage system to use to save the generated image.""" + cache_file_storage = None + """A Django storage system to use to save a generated cache file.""" image_cache_backend = None """ @@ -90,7 +90,8 @@ def __init__(self, source_file, **kwargs): self.kwargs = kwargs super(ImageSpec, self).__init__() - def get_filename(self): + @property + def cache_file_name(self): source_filename = self.source_file.name ext = suggest_extension(source_filename, self.format) return os.path.normpath(os.path.join( From 1fb1d83c5666fbb992c37427db8422f8092038c8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 6 Dec 2012 23:17:12 -0500 Subject: [PATCH 142/527] Add Thumbnail processor --- imagekit/processors/resize.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py index fea3d51d..624ccf67 100644 --- a/imagekit/processors/resize.py +++ b/imagekit/processors/resize.py @@ -215,3 +215,30 @@ def process(self, img): if self.mat_color is not None: img = ResizeCanvas(self.width, self.height, self.mat_color, anchor=self.anchor).process(img) return img + + +class Thumbnail(object): + """ + Resize the image for use as a thumbnail. Wraps ``ResizeToFill``, + ``ResizeToFit``, and ``SmartResize``. + + Note: while it doesn't currently, in the future this processor may also + sharpen based on the amount of reduction. + + """ + + def __init__(self, width=None, height=None, anchor='auto', crop=True): + self.width = width + self.height = height + self.anchor = anchor + self.crop = crop + + def process(self, img): + if self.crop: + if self.anchor == 'auto': + processor = SmartResize(self.width, self.height) + else: + processor = ResizeToFill(self.width, self.height, self.anchor) + else: + processor = ResizeToFit(self.width, self.height) + return processor.process(img) From c69c2d087e7481b4d36ff43d0eae240181cb75db Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 6 Dec 2012 23:48:09 -0500 Subject: [PATCH 143/527] Create Thumbnail spec; closes #175 --- imagekit/__init__.py | 1 + imagekit/generatorlibrary.py | 13 +++++++++++++ imagekit/processors/resize.py | 3 +++ 3 files changed, 17 insertions(+) create mode 100644 imagekit/generatorlibrary.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index 2c72bf44..e65c2707 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,6 +1,7 @@ # flake8: noqa from . import conf +from . import generatorlibrary from .specs import ImageSpec from .pkgmeta import * from .registry import register, unregister diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py new file mode 100644 index 00000000..17860224 --- /dev/null +++ b/imagekit/generatorlibrary.py @@ -0,0 +1,13 @@ +from .registry import register +from .processors import Thumbnail as ThumbnailProcessor +from .specs import ImageSpec + + +class Thumbnail(ImageSpec): + def __init__(self, width=None, height=None, anchor='auto', crop=True, **kwargs): + self.processors = [ThumbnailProcessor(width, height, anchor=anchor, + crop=crop)] + super(Thumbnail, self).__init__(**kwargs) + + +register.spec('ik:thumbnail', Thumbnail) diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py index 624ccf67..f241ca62 100644 --- a/imagekit/processors/resize.py +++ b/imagekit/processors/resize.py @@ -235,6 +235,9 @@ def __init__(self, width=None, height=None, anchor='auto', crop=True): def process(self, img): if self.crop: + if not self.width or not self.height: + raise Exception('You must provide both a width and height when' + ' cropping.') if self.anchor == 'auto': processor = SmartResize(self.width, self.height) else: From 30e40b4916418356fbde6c36f48ab5833a92006a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 7 Dec 2012 00:17:35 -0500 Subject: [PATCH 144/527] Add TODO for unregistration --- imagekit/registry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/registry.py b/imagekit/registry.py index c6d0150b..160c31e6 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -20,6 +20,7 @@ def register(self, id, generator): self._generators[id] = generator def unregister(self, id, generator): + # TODO: Either don't require the generator, or--if we do--assert that it's registered with the provided id try: del self._generators[id] except KeyError: From 52fb4e24bec4dd7accb67994d0165a4d5278f2c1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 7 Dec 2012 00:36:11 -0500 Subject: [PATCH 145/527] Add thumbnail templatetag Finally! --- imagekit/templatetags/imagekit.py | 102 +++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index a1731a5a..c9170119 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -73,38 +73,9 @@ def render(self, context): return mark_safe(u'' % attr_str) -#@register.tag -def generateimage(parser, token): - """ - Creates an image based on the provided arguments. - - By default:: - - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image %} - - generates an ```` tag:: - - - - You can add additional attributes to the tag using "with". For example, - this:: - - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image with alt="Hello!" %} - - will result in the following markup:: - - Hello! - - For more flexibility, ``generateimage`` also works as an assignment tag:: - - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image as th %} - - - """ - +def _generateimage(parser, bits): varname = None html_bits = [] - bits = token.split_contents() tag_name = bits.pop(0) if bits[-2] == ASSIGNMENT_DELIMETER: @@ -140,4 +111,75 @@ def generateimage(parser, token): return GenerateImageTagNode(generator_id, kwargs, html_kwargs) +#@register.tag +def generateimage(parser, token): + """ + Creates an image based on the provided arguments. + + By default:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image %} + + generates an ```` tag:: + + + + You can add additional attributes to the tag using "with". For example, + this:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image with alt="Hello!" %} + + will result in the following markup:: + + Hello! + + For more flexibility, ``generateimage`` also works as an assignment tag:: + + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image as th %} + + + """ + bits = token.split_contents() + return _generateimage(parser, bits) + + +#@register.tag +def thumbnail(parser, token): + """ + A convenient alias for the ``generateimage`` tag with the generator id + ``'ik:thumbnail'``. The following:: + + {% thumbnail from=mymodel.profile_image width=100 height=100 %} + + is equivalent to:: + + {% generateimage 'ik:thumbnail' from=mymodel.profile_image width=100 height=100 %} + + The thumbnail tag supports the "with" and "as" bits for adding html + attributes and assigning to a variable, respectively. It also accepts the + kwargs "width", "height", "anchor", and "crop". + + To use "smart cropping" (the ``SmartResize`` processor):: + + {% thumbnail from=mymodel.profile_image width=100 height=100 %} + + To crop, anchoring the image to the top right (the ``ResizeToFill`` + processor):: + + {% thumbnail from=mymodel.profile_image width=100 height=100 anchor='tr' %} + + To resize without cropping (using the ``ResizeToFit`` processor):: + + {% thumbnail from=mymodel.profile_image width=100 height=100 crop=0 %} + + """ + # TODO: Support positional arguments for this tag for "from", "width" and "height". + # Example: + # {% thumbnail mymodel.profile_image 100 100 anchor='tl' %} + bits = token.split_contents() + bits.insert(1, "'ik:thumbnail'") + return _generateimage(parser, bits) + + generateimage = register.tag(generateimage) +thumbnail = register.tag(thumbnail) From 184c13dd4e51c2453c6b6abeea1acdf49ffa7cd3 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 11 Dec 2012 22:33:33 -0500 Subject: [PATCH 146/527] More source_group renaming --- .../management/commands/warmimagecache.py | 4 +- imagekit/registry.py | 38 +++++++++---------- imagekit/specs/sourcegroups.py | 28 +++++++------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 21db47c1..35695af7 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -19,8 +19,8 @@ def handle(self, *args, **options): for spec_id in specs: self.stdout.write('Validating spec: %s\n' % spec_id) - for source in source_group_registry.get(spec_id): - for source_file in source.files(): + for source_group in source_group_registry.get(spec_id): + for source_file in source_group.files(): if source_file: spec = generator_registry.get(spec_id, source_file=source_file) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) self.stdout.write(' %s\n' % source_file) diff --git a/imagekit/registry.py b/imagekit/registry.py index 160c31e6..bdf3fd67 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -53,57 +53,57 @@ class SourceGroupRegistry(object): """ - _source_signals = [ + _signals = [ source_created, source_changed, source_deleted, ] def __init__(self): - self._sources = {} - for signal in self._source_signals: - signal.connect(self.source_receiver) + self._source_groups = {} + for signal in self._signals: + signal.connect(self.source_group_receiver) before_access.connect(self.before_access_receiver) - def register(self, spec_id, sources): + def register(self, spec_id, source_groups): """ - Associates sources with a spec id + Associates source groups with a spec id """ - for source in sources: - if source not in self._sources: - self._sources[source] = set() - self._sources[source].add(spec_id) + for source_group in source_groups: + if source_group not in self._source_groups: + self._source_groups[source_group] = set() + self._source_groups[source_group].add(spec_id) - def unregister(self, spec_id, sources): + def unregister(self, spec_id, source_groups): """ Disassociates sources with a spec id """ - for source in sources: + for source_group in source_groups: try: - self._sources[source].remove(spec_id) + self._source_groups[source_group].remove(spec_id) except KeyError: continue def get(self, spec_id): - return [source for source in self._sources - if spec_id in self._sources[source]] + return [source_group for source_group in self._source_groups + if spec_id in self._source_groups[source_group]] def before_access_receiver(self, sender, generator, file, **kwargs): generator.image_cache_strategy.invoke_callback('before_access', file) - def source_receiver(self, sender, source_file, signal, info, **kwargs): + def source_group_receiver(self, sender, source_file, signal, info, **kwargs): """ Redirects signals dispatched on sources to the appropriate specs. """ - source = sender - if source not in self._sources: + source_group = sender + if source_group not in self._source_groups: return for spec in (generator_registry.get(id, source_file=source_file, **info) - for id in self._sources[source]): + for id in self._sources_groups[source_group]): event_name = { source_created: 'source_created', source_changed: 'source_changed', diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 551d8598..fe0b3661 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -11,27 +11,27 @@ def ik_model_receiver(fn): """ @wraps(fn) def receiver(self, sender, **kwargs): - if sender in (src.model_class for src in self._sources): + if sender in (src.model_class for src in self._source_groups): fn(self, sender=sender, **kwargs) return receiver class ModelSignalRouter(object): """ - Handles signals dispatched by models and relays them to the spec sources - that represent those models. + Handles signals dispatched by models and relays them to the spec source + groups that represent those models. """ def __init__(self): - self._sources = [] + self._source_groups = [] uid = 'ik_spec_field_receivers' post_init.connect(self.post_init_receiver, dispatch_uid=uid) post_save.connect(self.post_save_receiver, dispatch_uid=uid) post_delete.connect(self.post_delete_receiver, dispatch_uid=uid) - def add(self, source): - self._sources.append(source) + def add(self, source_group): + self._source_groups.append(source_group) def init_instance(self, instance): instance._ik = getattr(instance, '_ik', {}) @@ -55,7 +55,7 @@ def get_field_dict(self, instance): """ return dict((src.image_field, getattr(instance, src.image_field)) for - src in self._sources if src.model_class is instance.__class__) + src in self._source_groups if src.model_class is instance.__class__) @ik_model_receiver def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): @@ -82,19 +82,19 @@ def post_init_receiver(self, sender, instance=None, **kwargs): def dispatch_signal(self, signal, file, model_class, instance, attname): """ - Dispatch the signal for each of the matching sources. Note that more - than one source can have the same model and image_field; it's important - that we dispatch the signal for each. + Dispatch the signal for each of the matching source groups. Note that + more than one source can have the same model and image_field; it's + important that we dispatch the signal for each. """ - for source in self._sources: - if source.model_class is model_class and source.image_field == attname: + for source_group in self._source_groups: + if source_group.model_class is model_class and source_group.image_field == attname: info = dict( - source=source, + source_group=source_group, instance=instance, field_name=attname, ) - signal.send(sender=source, source_file=file, info=info) + signal.send(sender=source_group, source_file=file, info=info) class ImageFieldSourceGroup(object): From d80f2f26a99fbedd8f8bae6bd46cef51efe16ebf Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 11 Dec 2012 22:53:13 -0500 Subject: [PATCH 147/527] "source" now refers to the file itself --- imagekit/admin.py | 2 +- imagekit/management/commands/warmimagecache.py | 8 ++++---- imagekit/models/fields/utils.py | 6 +++--- imagekit/registry.py | 6 +++--- imagekit/specs/__init__.py | 14 +++++++------- imagekit/specs/sourcegroups.py | 2 +- imagekit/templatetags/imagekit.py | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/imagekit/admin.py b/imagekit/admin.py index 7a9e1454..6b37a4c4 100644 --- a/imagekit/admin.py +++ b/imagekit/admin.py @@ -30,7 +30,7 @@ def __call__(self, obj): raise Exception('The property %s is not defined on %s.' % (self.image_field, obj.__class__.__name__)) - original_image = getattr(thumbnail, 'source_file', None) or thumbnail + original_image = getattr(thumbnail, 'source', None) or thumbnail template = self.template or 'imagekit/admin/thumbnail.html' return render_to_string(template, { diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 35695af7..6c9822dd 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -20,10 +20,10 @@ def handle(self, *args, **options): for spec_id in specs: self.stdout.write('Validating spec: %s\n' % spec_id) for source_group in source_group_registry.get(spec_id): - for source_file in source_group.files(): - if source_file: - spec = generator_registry.get(spec_id, source_file=source_file) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) - self.stdout.write(' %s\n' % source_file) + for source in source_group.files(): + if source: + spec = generator_registry.get(spec_id, source=source) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) + self.stdout.write(' %s\n' % source) try: # TODO: Allow other validation actions through command option GeneratedImageCacheFile(spec).validate() diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 07c6e9e7..39dbc528 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -13,7 +13,7 @@ def __get__(self, instance, owner): else: field_name = getattr(self.field, 'source', None) if field_name: - source_file = getattr(instance, field_name) + source = getattr(instance, field_name) else: image_fields = [getattr(instance, f.attname) for f in instance.__class__._meta.fields if @@ -28,8 +28,8 @@ def __get__(self, instance, owner): ' ImageSpecField.' % (instance.__class__.__name__, self.attname)) else: - source_file = image_fields[0] - spec = self.field.get_spec(source_file=source_file) # TODO: What "hints" should we pass here? + source = image_fields[0] + spec = self.field.get_spec(source=source) # TODO: What "hints" should we pass here? file = GeneratedImageCacheFile(spec) instance.__dict__[self.attname] = file return file diff --git a/imagekit/registry.py b/imagekit/registry.py index bdf3fd67..6ff92109 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -93,7 +93,7 @@ def get(self, spec_id): def before_access_receiver(self, sender, generator, file, **kwargs): generator.image_cache_strategy.invoke_callback('before_access', file) - def source_group_receiver(self, sender, source_file, signal, info, **kwargs): + def source_group_receiver(self, sender, source, signal, info, **kwargs): """ Redirects signals dispatched on sources to the appropriate specs. @@ -102,14 +102,14 @@ def source_group_receiver(self, sender, source_file, signal, info, **kwargs): if source_group not in self._source_groups: return - for spec in (generator_registry.get(id, source_file=source_file, **info) + for spec in (generator_registry.get(id, source=source, **info) for id in self._sources_groups[source_group]): event_name = { source_created: 'source_created', source_changed: 'source_changed', source_deleted: 'source_deleted', } - spec._handle_source_event(event_name, source_file) + spec._handle_source_event(event_name, source) class Register(object): diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index fdf20444..de1db8da 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -45,7 +45,7 @@ def generate(self): raise NotImplementedError # TODO: I don't like this interface. Is there a standard Python one? pubsub? - def _handle_source_event(self, event_name, source_file): + def _handle_source_event(self, event_name, source): file = GeneratedImageCacheFile(self) self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) @@ -84,15 +84,15 @@ class ImageSpec(BaseImageSpec): """ - def __init__(self, source_file, **kwargs): - self.source_file = source_file + def __init__(self, source, **kwargs): + self.source = source self.processors = self.processors or [] self.kwargs = kwargs super(ImageSpec, self).__init__() @property def cache_file_name(self): - source_filename = self.source_file.name + source_filename = self.source.name ext = suggest_extension(source_filename, self.format) return os.path.normpath(os.path.join( settings.IMAGEKIT_CACHE_DIR, @@ -104,7 +104,7 @@ def cache_file_name(self): def get_hash(self): return md5(pickle.dumps([ - self.source_file, + self.source, self.kwargs, self.processors, self.format, @@ -115,9 +115,9 @@ def get_hash(self): def generate(self): # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) - source_file = self.source_file + source = self.source filename = self.kwargs.get('filename') - img = open_image(source_file) + img = open_image(source) original_format = img.format # Run the processors diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index fe0b3661..b36b211b 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -94,7 +94,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): instance=instance, field_name=attname, ) - signal.send(sender=source_group, source_file=file, info=info) + signal.send(sender=source_group, source=file, info=info) class ImageFieldSourceGroup(object): diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index c9170119..d5aa9c6f 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -14,7 +14,7 @@ _kwarg_map = { - 'from': 'source_file', + 'from': 'source', } From faee0fa5371a6779550b56803e848869285a0455 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 8 Jan 2013 20:36:17 -0500 Subject: [PATCH 148/527] Correct typo --- imagekit/registry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index 6ff92109..8d082cdb 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -103,7 +103,7 @@ def source_group_receiver(self, sender, source, signal, info, **kwargs): return for spec in (generator_registry.get(id, source=source, **info) - for id in self._sources_groups[source_group]): + for id in self._source_groups[source_group]): event_name = { source_created: 'source_created', source_changed: 'source_changed', From c2dedaa2b87e293697be7fea9c808e95e20c0bb7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 8 Jan 2013 20:57:19 -0500 Subject: [PATCH 149/527] Use file name; not file, which can't be pickled --- imagekit/specs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index de1db8da..79ff1071 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -104,7 +104,7 @@ def cache_file_name(self): def get_hash(self): return md5(pickle.dumps([ - self.source, + self.source.name, self.kwargs, self.processors, self.format, From 658bb22c783fe9e50db66773782e3a7fcdbfbaba Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 8 Jan 2013 21:52:56 -0500 Subject: [PATCH 150/527] Special case serialization of ImageFieldFiles Closes #168 --- imagekit/specs/__init__.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 79ff1071..e9e72cf4 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.db.models.fields.files import ImageFieldFile from hashlib import md5 import os import pickle @@ -102,6 +103,25 @@ def cache_file_name(self): return os.path.join(settings.IMAGEKIT_CACHE_DIR, '%s%s' % (hash, ext)) + def __getstate__(self): + state = self.__dict__ + + # Unpickled ImageFieldFiles won't work (they're missing a storage + # object). Since they're such a common use case, we special case them. + if isinstance(self.source, ImageFieldFile): + field = getattr(self.source, 'field') + state['_field_data'] = { + 'instance': getattr(self.source, 'instance', None), + 'attname': getattr(field, 'name', None), + } + return state + + def __setstate__(self, state): + field_data = state.pop('_field_data', None) + self.__dict__ = state + if field_data: + self.source = getattr(field_data['instance'], field_data['attname']) + def get_hash(self): return md5(pickle.dumps([ self.source.name, From 11d511f9ccfdc83927e7c8ed9917f7c195d2b295 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 8 Jan 2013 22:39:02 -0500 Subject: [PATCH 151/527] Extract util for parsing common bits. In preparation for new thumbnail and placeholder tag syntaxes (#177 and #176) which share some (but not all) syntax with the generateimage tag. --- imagekit/templatetags/imagekit.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index d5aa9c6f..c2c6363e 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -73,9 +73,15 @@ def render(self, context): return mark_safe(u'' % attr_str) -def _generateimage(parser, bits): +def parse_ik_tag_bits(parser, bits): + """ + Parses the tag name, html attributes and variable name (for assignment tags) + from the provided bits. The preceding bits may vary and are left to be + parsed by specific tags. + + """ varname = None - html_bits = [] + html_attrs = {} tag_name = bits.pop(0) if bits[-2] == ASSIGNMENT_DELIMETER: @@ -90,6 +96,19 @@ def _generateimage(parser, bits): raise template.TemplateSyntaxError('Don\'t use "%s" unless you\'re' ' setting html attributes.' % HTML_ATTRS_DELIMITER) + args, html_attrs = parse_bits(parser, html_bits, [], 'args', + 'kwargs', None, False, tag_name) + if len(args): + raise template.TemplateSyntaxError('All "%s" tag arguments after' + ' the "%s" token must be named.' % (tag_name, + HTML_ATTRS_DELIMITER)) + + return (tag_name, bits, html_attrs, varname) + + +def _generateimage(parser, bits): + tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) + args, kwargs = parse_bits(parser, bits, ['generator_id'], 'args', 'kwargs', None, False, tag_name) @@ -102,13 +121,7 @@ def _generateimage(parser, bits): if varname: return GenerateImageAssignmentNode(varname, generator_id, kwargs) else: - html_args, html_kwargs = parse_bits(parser, html_bits, [], 'args', - 'kwargs', None, False, tag_name) - if len(html_args): - raise template.TemplateSyntaxError('All "%s" tag arguments after' - ' the "%s" token must be named.' % (tag_name, - HTML_ATTRS_DELIMITER)) - return GenerateImageTagNode(generator_id, kwargs, html_kwargs) + return GenerateImageTagNode(generator_id, kwargs, html_attrs) #@register.tag From 3177eb8e192d96396095547c0a075995796e3e1c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 8 Jan 2013 23:36:22 -0500 Subject: [PATCH 152/527] Extract utils for use in other modules --- tests/test_generateimage_tag.py | 16 ++-------------- tests/utils.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 95face71..35c29d84 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,19 +1,7 @@ -from bs4 import BeautifulSoup -from django.template import Context, Template, TemplateSyntaxError +from django.template import TemplateSyntaxError from nose.tools import eq_, assert_not_in, raises, assert_not_equal from . import imagespecs # noqa -from .utils import get_image_file - - -def render_tag(ttag): - img = get_image_file() - template = Template('{%% load imagekit %%}%s' % ttag) - context = Context({'img': img}) - return template.render(context) - - -def get_html_attrs(ttag): - return BeautifulSoup(render_tag(ttag)).img.attrs +from .utils import render_tag, get_html_attrs def test_img_tag(): diff --git a/tests/utils.py b/tests/utils.py index 3093b7d3..1a4e3fcc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,6 +1,8 @@ +from bs4 import BeautifulSoup import os from django.conf import settings from django.core.files.base import ContentFile +from django.template import Context, Template from imagekit.lib import Image, StringIO import pickle from .models import Photo @@ -42,3 +44,14 @@ def pickleback(obj): pickle.dump(obj, pickled) pickled.seek(0) return pickle.load(pickled) + + +def render_tag(ttag): + img = get_image_file() + template = Template('{%% load imagekit %%}%s' % ttag) + context = Context({'img': img}) + return template.render(context) + + +def get_html_attrs(ttag): + return BeautifulSoup(render_tag(ttag)).img.attrs From 43a1f494984491701770589b6d3ff906d086ba5a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 9 Jan 2013 00:25:08 -0500 Subject: [PATCH 153/527] New thumbnail tag syntax! Closes #177 --- imagekit/generatorlibrary.py | 2 +- imagekit/processors/resize.py | 17 +++- imagekit/templatetags/imagekit.py | 138 ++++++++++++++++++++++++++---- 3 files changed, 137 insertions(+), 20 deletions(-) diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index 17860224..bd9da9a6 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -4,7 +4,7 @@ class Thumbnail(ImageSpec): - def __init__(self, width=None, height=None, anchor='auto', crop=True, **kwargs): + def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): self.processors = [ThumbnailProcessor(width, height, anchor=anchor, crop=crop)] super(Thumbnail, self).__init__(**kwargs) diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py index f241ca62..0bae1225 100644 --- a/imagekit/processors/resize.py +++ b/imagekit/processors/resize.py @@ -227,11 +227,24 @@ class Thumbnail(object): """ - def __init__(self, width=None, height=None, anchor='auto', crop=True): + def __init__(self, width=None, height=None, anchor=None, crop=None): self.width = width self.height = height - self.anchor = anchor + if anchor: + if crop is False: + raise Exception("You can't specify an anchor point if crop is False.") + else: + crop = True + elif crop is None: + # Assume we are cropping if both a width and height are provided. If + # only one is, we must be resizing to fit. + crop = width is not None and height is not None + + # A default anchor if cropping. + if crop and anchor is None: + anchor = 'auto' self.crop = crop + self.anchor = anchor def process(self, img): if self.crop: diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index c2c6363e..457d13bd 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -11,6 +11,7 @@ ASSIGNMENT_DELIMETER = 'as' HTML_ATTRS_DELIMITER = 'with' +DEFAULT_THUMBNAIL_GENERATOR = 'ik:thumbnail' _kwarg_map = { @@ -18,7 +19,7 @@ } -def get_cache_file(context, generator_id, generator_kwargs): +def get_cache_file(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, v in generator_kwargs.items()) @@ -26,6 +27,17 @@ def get_cache_file(context, generator_id, generator_kwargs): return GeneratedImageCacheFile(generator) +def parse_dimensions(dimensions): + """ + Parse the width and height values from a dimension string. Valid values are + '1x1', '1x', and 'x1'. If one of the dimensions is omitted, the parse result + will be None for that value. + + """ + width, height = [d.strip() or None for d in dimensions.split('x')] + return dict(width=width, height=height) + + class GenerateImageAssignmentNode(template.Node): def __init__(self, variable_name, generator_id, generator_kwargs): @@ -62,8 +74,75 @@ def render(self, context): attrs = dict((k, v.resolve(context)) for k, v in self._html_attrs.items()) - # Only add width and height if neither is specified (for proportional - # scaling). + # Only add width and height if neither is specified (to allow for + # proportional in-browser scaling). + if not 'width' in attrs and not 'height' in attrs: + attrs.update(width=file.width, height=file.height) + + attrs['src'] = file.url + attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in + attrs.items()) + return mark_safe(u'' % attr_str) + + +class ThumbnailAssignmentNode(template.Node): + + def __init__(self, variable_name, generator_id, dimensions, source, generator_kwargs): + self._variable_name = variable_name + self._generator_id = generator_id + self._dimensions = dimensions + self._source = source + self._generator_kwargs = generator_kwargs + + def get_variable_name(self, context): + return unicode(self._variable_name) + + def render(self, context): + from ..utils import autodiscover + autodiscover() + + variable_name = self.get_variable_name(context) + + generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR + kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, + v in self._generator_kwargs.items()) + kwargs['source'] = self._source.resolve(context) + kwargs.update(parse_dimensions(self._dimensions.resolve(context))) + generator = generator_registry.get(generator_id, **kwargs) + + context[variable_name] = GeneratedImageCacheFile(generator) + + return '' + + +class ThumbnailImageTagNode(template.Node): + + def __init__(self, generator_id, dimensions, source, generator_kwargs, html_attrs): + self._generator_id = generator_id + self._dimensions = dimensions + self._source = source + self._generator_kwargs = generator_kwargs + self._html_attrs = html_attrs + + def render(self, context): + from ..utils import autodiscover + autodiscover() + + generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR + dimensions = parse_dimensions(self._dimensions.resolve(context)) + kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, + v in self._generator_kwargs.items()) + kwargs['source'] = self._source.resolve(context) + kwargs.update(dimensions) + generator = generator_registry.get(generator_id, **kwargs) + + file = GeneratedImageCacheFile(generator) + + attrs = dict((k, v.resolve(context)) for k, v in + self._html_attrs.items()) + + # Only add width and height if neither is specified (to allow for + # proportional in-browser scaling). if not 'width' in attrs and not 'height' in attrs: attrs.update(width=file.width, height=file.height) @@ -84,10 +163,17 @@ def parse_ik_tag_bits(parser, bits): html_attrs = {} tag_name = bits.pop(0) - if bits[-2] == ASSIGNMENT_DELIMETER: + if len(bits) >= 2 and bits[-2] == ASSIGNMENT_DELIMETER: varname = bits[-1] bits = bits[:-2] - elif HTML_ATTRS_DELIMITER in bits: + + if HTML_ATTRS_DELIMITER in bits: + + if varname: + raise template.TemplateSyntaxError('Do not specify html attributes' + ' (using "%s") when using the "%s" tag as an assignment' + ' tag.' % (HTML_ATTRS_DELIMITER, tag_name)) + index = bits.index(HTML_ATTRS_DELIMITER) html_bits = bits[index + 1:] bits = bits[:index] @@ -159,10 +245,9 @@ def generateimage(parser, token): #@register.tag def thumbnail(parser, token): """ - A convenient alias for the ``generateimage`` tag with the generator id - ``'ik:thumbnail'``. The following:: + A convenient shortcut syntax for generating a thumbnail. The following:: - {% thumbnail from=mymodel.profile_image width=100 height=100 %} + {% thumbnail '100x100' mymodel.profile_image %} is equivalent to:: @@ -170,28 +255,47 @@ def thumbnail(parser, token): The thumbnail tag supports the "with" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the - kwargs "width", "height", "anchor", and "crop". + kwargs "anchor", and "crop". To use "smart cropping" (the ``SmartResize`` processor):: - {% thumbnail from=mymodel.profile_image width=100 height=100 %} + {% thumbnail '100x100' mymodel.profile_image %} To crop, anchoring the image to the top right (the ``ResizeToFill`` processor):: - {% thumbnail from=mymodel.profile_image width=100 height=100 anchor='tr' %} + {% thumbnail '100x100' mymodel.profile_image anchor='tr' %} To resize without cropping (using the ``ResizeToFit`` processor):: - {% thumbnail from=mymodel.profile_image width=100 height=100 crop=0 %} + {% thumbnail '100x100' mymodel.profile_image crop=0 %} """ - # TODO: Support positional arguments for this tag for "from", "width" and "height". - # Example: - # {% thumbnail mymodel.profile_image 100 100 anchor='tl' %} bits = token.split_contents() - bits.insert(1, "'ik:thumbnail'") - return _generateimage(parser, bits) + + tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) + + args, kwargs = parse_bits(parser, bits, [], 'args', 'kwargs', + None, False, tag_name) + + if len(args) < 2: + raise template.TemplateSyntaxError('The "%s" tag requires at least two' + ' unnamed arguments: the dimensions and the source image.' + % tag_name) + elif len(args) > 3: + raise template.TemplateSyntaxError('The "%s" tag accepts at most three' + ' unnamed arguments: a generator id, the dimensions, and the' + ' source image.' % tag_name) + + dimensions, source = args[-2:] + generator_id = args[0] if len(args) > 2 else None + + if varname: + return ThumbnailAssignmentNode(varname, generator_id, dimensions, + source, kwargs) + else: + return ThumbnailImageTagNode(generator_id, dimensions, source, kwargs, + html_attrs) generateimage = register.tag(generateimage) From 219b8507ad35f91917fcd367a5637ea8d25793fe Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 9 Jan 2013 00:25:28 -0500 Subject: [PATCH 154/527] Add thumbnail tag tests --- tests/imagespecs.py | 8 +++++ tests/test_thumbnail_tag.py | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/test_thumbnail_tag.py diff --git a/tests/imagespecs.py b/tests/imagespecs.py index 8a699751..06d2dab1 100644 --- a/tests/imagespecs.py +++ b/tests/imagespecs.py @@ -1,8 +1,16 @@ from imagekit import ImageSpec, register +from imagekit.processors import ResizeToFill class TestSpec(ImageSpec): pass +class ResizeTo1PixelSquare(ImageSpec): + def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): + self.processors = [ResizeToFill(1, 1)] + super(ResizeTo1PixelSquare, self).__init__(**kwargs) + + register.spec('testspec', TestSpec) +register.spec('1pxsq', ResizeTo1PixelSquare) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py new file mode 100644 index 00000000..70f3f4dd --- /dev/null +++ b/tests/test_thumbnail_tag.py @@ -0,0 +1,66 @@ +from django.template import TemplateSyntaxError +from nose.tools import eq_, assert_not_in, raises, assert_not_equal +from . import imagespecs # noqa +from .utils import render_tag, get_html_attrs + + +def test_img_tag(): + ttag = r"""{% thumbnail '100x100' img %}""" + attrs = get_html_attrs(ttag) + expected_attrs = set(['src', 'width', 'height']) + eq_(set(attrs.keys()), expected_attrs) + for k in expected_attrs: + assert_not_equal(attrs[k].strip(), '') + + +def test_img_tag_attrs(): + ttag = r"""{% thumbnail '100x100' img with alt="Hello" %}""" + attrs = get_html_attrs(ttag) + eq_(attrs.get('alt'), 'Hello') + + +@raises(TemplateSyntaxError) +def test_dangling_with(): + ttag = r"""{% thumbnail '100x100' img with %}""" + render_tag(ttag) + + +@raises(TemplateSyntaxError) +def test_not_enough_args(): + ttag = r"""{% thumbnail '100x100' %}""" + render_tag(ttag) + + +@raises(TemplateSyntaxError) +def test_too_many_args(): + ttag = r"""{% thumbnail 'generator_id' '100x100' img 'extra' %}""" + render_tag(ttag) + + +@raises(TemplateSyntaxError) +def test_with_assignment(): + """ + You can either use thumbnail as an assigment tag or specify html attrs, + but not both. + + """ + ttag = r"""{% thumbnail '100x100' img with alt="Hello" as th %}""" + render_tag(ttag) + + +def test_assignment_tag(): + ttag = r"""{% thumbnail '100x100' img as th %}{{ th.url }}""" + html = render_tag(ttag) + assert_not_equal(html, '') + + +def test_single_dimension(): + ttag = r"""{% thumbnail '100x' img as th %}{{ th.width }}""" + html = render_tag(ttag) + eq_(html, '100') + + +def test_alternate_generator(): + ttag = r"""{% thumbnail '1pxsq' '100x' img as th %}{{ th.width }}""" + html = render_tag(ttag) + eq_(html, '1') From 5acce98223df75b2e482ed754ffa8325e286fa08 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 9 Jan 2013 00:26:47 -0500 Subject: [PATCH 155/527] Remove extra space --- tests/test_generateimage_tag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 35c29d84..76ad2a51 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -47,6 +47,6 @@ def test_single_dimension_attr(): def test_assignment_tag(): - ttag = r"""{% generateimage 'testspec' from=img as th %} {{ th.url }}""" + ttag = r"""{% generateimage 'testspec' from=img as th %}{{ th.url }}""" html = render_tag(ttag) assert_not_equal(html.strip(), '') From e5b15d09bdc74f3c67dd37fa197644456ba62ae7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 9 Jan 2013 00:28:29 -0500 Subject: [PATCH 156/527] Remove _generateimage utility. --- imagekit/templatetags/imagekit.py | 35 ++++++++++++++----------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 457d13bd..9daacc26 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -192,24 +192,6 @@ def parse_ik_tag_bits(parser, bits): return (tag_name, bits, html_attrs, varname) -def _generateimage(parser, bits): - tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) - - args, kwargs = parse_bits(parser, bits, ['generator_id'], 'args', 'kwargs', - None, False, tag_name) - - if len(args) != 1: - raise template.TemplateSyntaxError('The "%s" tag requires exactly one' - ' unnamed argument (the generator id).' % tag_name) - - generator_id = args[0] - - if varname: - return GenerateImageAssignmentNode(varname, generator_id, kwargs) - else: - return GenerateImageTagNode(generator_id, kwargs, html_attrs) - - #@register.tag def generateimage(parser, token): """ @@ -239,7 +221,22 @@ def generateimage(parser, token): """ bits = token.split_contents() - return _generateimage(parser, bits) + + tag_name, bits, html_attrs, varname = parse_ik_tag_bits(parser, bits) + + args, kwargs = parse_bits(parser, bits, ['generator_id'], 'args', 'kwargs', + None, False, tag_name) + + if len(args) != 1: + raise template.TemplateSyntaxError('The "%s" tag requires exactly one' + ' unnamed argument (the generator id).' % tag_name) + + generator_id = args[0] + + if varname: + return GenerateImageAssignmentNode(varname, generator_id, kwargs) + else: + return GenerateImageTagNode(generator_id, kwargs, html_attrs) #@register.tag From 8c5a571293d7b799df027d1e8664840c09638d8a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 13 Jan 2013 23:35:19 -0500 Subject: [PATCH 157/527] Remove unused import Fixes flake8 error --- tests/test_thumbnail_tag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 70f3f4dd..5fdbbb2c 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,5 +1,5 @@ from django.template import TemplateSyntaxError -from nose.tools import eq_, assert_not_in, raises, assert_not_equal +from nose.tools import eq_, raises, assert_not_equal from . import imagespecs # noqa from .utils import render_tag, get_html_attrs From 4ecfa5d35e962af1cebf4bf70bc2491b6cf34e4b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 13 Jan 2013 23:40:26 -0500 Subject: [PATCH 158/527] Don't rely on source filename being relative path Closes #180 --- imagekit/specs/__init__.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e9e72cf4..9bfab2cb 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -93,15 +93,20 @@ def __init__(self, source, **kwargs): @property def cache_file_name(self): - source_filename = self.source.name - ext = suggest_extension(source_filename, self.format) - return os.path.normpath(os.path.join( - settings.IMAGEKIT_CACHE_DIR, - os.path.splitext(source_filename)[0], - '%s%s' % (self.get_hash(), ext))) - - return os.path.join(settings.IMAGEKIT_CACHE_DIR, - '%s%s' % (hash, ext)) + source_filename = getattr(self.source, 'name', None) + + if source_filename is None or os.path.isabs(source_filename): + # Generally, we put the file right in the cache directory. + dir = settings.IMAGEKIT_CACHE_DIR + else: + # For source files with relative names (like Django media files), + # use the source's name to create the new filename. + dir = os.path.join(settings.IMAGEKIT_CACHE_DIR, + os.path.splitext(source_filename)[0]) + + ext = suggest_extension(source_filename or '', self.format) + return os.path.normpath(os.path.join(dir, + '%s%s' % (self.get_hash(), ext))) def __getstate__(self): state = self.__dict__ From d632fc70fab17d962f26369b4f2e0460430f4298 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 21:27:21 -0500 Subject: [PATCH 159/527] Copy contents to NamedTemporaryFile if generated file has no name --- imagekit/files.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/imagekit/files.py b/imagekit/files.py index 9916c2ca..b4efd845 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -3,6 +3,7 @@ from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode import os +from tempfile import NamedTemporaryFile from .signals import before_access from .utils import (format_to_mimetype, extension_to_mimetype, get_logger, get_singleton) @@ -116,7 +117,16 @@ def validate(self): def generate(self): # Generate the file content = self.generator.generate() - actual_name = self.storage.save(self.name, content) + + # If the file doesn't have a name, Django will raise an Exception while + # trying to save it, so we create a named temporary file. + if not getattr(content, 'name', None): + f = NamedTemporaryFile() + f.write(content.read()) + f.seek(0) + content = f + + actual_name = self.storage.save(self.name, File(content)) if actual_name != self.name: get_logger().warning('The storage backend %s did not save the file' From eef1e41448ad11e0a0e78f3515123226388fde46 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 21:28:23 -0500 Subject: [PATCH 160/527] Remove code that used old filename kwarg --- imagekit/specs/__init__.py | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 9bfab2cb..e05aac83 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,15 +1,14 @@ from django.conf import settings +from django.core.files import File from django.db.models.fields.files import ImageFieldFile from hashlib import md5 import os import pickle -from ..exceptions import UnknownExtensionError -from ..files import GeneratedImageCacheFile, IKContentFile +from ..files import GeneratedImageCacheFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..processors import ProcessorPipeline -from ..utils import (open_image, extension_to_format, img_to_fobj, - suggest_extension) +from ..utils import open_image, img_to_fobj, suggest_extension from ..registry import generator_registry, register @@ -140,9 +139,7 @@ def get_hash(self): def generate(self): # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) - source = self.source - filename = self.kwargs.get('filename') - img = open_image(source) + img = open_image(self.source) original_format = img.format # Run the processors @@ -150,22 +147,8 @@ def generate(self): img = ProcessorPipeline(processors or []).process(img) options = dict(self.options or {}) - - # Determine the format. - format = self.format - if filename and not format: - # Try to guess the format from the extension. - extension = os.path.splitext(filename)[1].lower() - if extension: - try: - format = extension_to_format(extension) - except UnknownExtensionError: - pass - format = format or img.format or original_format or 'JPEG' - - imgfile = img_to_fobj(img, format, **options) - # TODO: Is this the right place to wrap the file? Can we use a mixin instead? Is it even still having the desired effect? Re: #111 - content = IKContentFile(filename, imgfile.read(), format=format) + format = self.format or img.format or original_format or 'JPEG' + content = img_to_fobj(img, format, **options) return content From 6ff1d35fbea771a692fe7e650ed6889e922fe819 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 21:31:53 -0500 Subject: [PATCH 161/527] Remove unused import --- imagekit/specs/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index e05aac83..062f239d 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,5 +1,4 @@ from django.conf import settings -from django.core.files import File from django.db.models.fields.files import ImageFieldFile from hashlib import md5 import os From 4737ac64c43a2af4a892f93fe6df19b4c9288407 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 21:35:38 -0500 Subject: [PATCH 162/527] Specs no longer accept arbitrary kwargs Only the source. --- imagekit/management/commands/warmimagecache.py | 2 +- imagekit/models/fields/utils.py | 2 +- imagekit/registry.py | 2 +- imagekit/specs/__init__.py | 10 ++++------ 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 6c9822dd..2d147f5c 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -22,7 +22,7 @@ def handle(self, *args, **options): for source_group in source_group_registry.get(spec_id): for source in source_group.files(): if source: - spec = generator_registry.get(spec_id, source=source) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) + spec = generator_registry.get(spec_id, source=source) self.stdout.write(' %s\n' % source) try: # TODO: Allow other validation actions through command option diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 39dbc528..2324a338 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -29,7 +29,7 @@ def __get__(self, instance, owner): self.attname)) else: source = image_fields[0] - spec = self.field.get_spec(source=source) # TODO: What "hints" should we pass here? + spec = self.field.get_spec(source=source) file = GeneratedImageCacheFile(spec) instance.__dict__[self.attname] = file return file diff --git a/imagekit/registry.py b/imagekit/registry.py index 8d082cdb..9c0f4b85 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -102,7 +102,7 @@ def source_group_receiver(self, sender, source, signal, info, **kwargs): if source_group not in self._source_groups: return - for spec in (generator_registry.get(id, source=source, **info) + for spec in (generator_registry.get(id, source=source) for id in self._source_groups[source_group]): event_name = { source_created: 'source_created', diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 062f239d..d2b154bb 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -36,7 +36,7 @@ class BaseImageSpec(object): """ - def __init__(self, **kwargs): + def __init__(self): self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) @@ -83,10 +83,9 @@ class ImageSpec(BaseImageSpec): """ - def __init__(self, source, **kwargs): + def __init__(self, source): self.source = source self.processors = self.processors or [] - self.kwargs = kwargs super(ImageSpec, self).__init__() @property @@ -128,7 +127,6 @@ def __setstate__(self, state): def get_hash(self): return md5(pickle.dumps([ self.source.name, - self.kwargs, self.processors, self.format, self.options, @@ -212,7 +210,7 @@ def set_spec_id(self, id): self.spec_id = id register.spec(id, self._original_spec) - def get_spec(self, **kwargs): + def get_spec(self, source): """ Look up the spec by the spec id. We do this (instead of storing the spec as an attribute) so that users can override apps' specs--without @@ -222,4 +220,4 @@ def get_spec(self, **kwargs): """ if not getattr(self, 'spec_id', None): raise Exception('Object %s has no spec id.' % self) - return generator_registry.get(self.spec_id, **kwargs) + return generator_registry.get(self.spec_id, source=source) From d52b9c810006c3551e286739c0238f268c958a6f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 21:47:54 -0500 Subject: [PATCH 163/527] Add utility for extracting field info --- imagekit/utils.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/imagekit/utils.py b/imagekit/utils.py index ac93cf64..e6c29434 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -382,3 +382,22 @@ def get_logger(logger_name='imagekit', add_null_handler=True): if add_null_handler: logger.addHandler(logging.NullHandler()) return logger + + +def get_field_info(field_file): + """ + A utility for easily extracting information about the host model from a + Django FileField (or subclass). This is especially useful for when you want + to alter processors based on a property of the source model. For example:: + + class MySpec(ImageSpec): + def __init__(self, source): + instance, attname = get_field_info(source) + self.processors = [SmartResize(instance.thumbnail_width, + instance.thumbnail_height)] + + """ + return ( + getattr(field_file, 'instance', None), + getattr(getattr(field_file, 'field', None), 'attname', None), + ) From 9dd7bef709a53cd8757fb04ee07eaa61740d7fed Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:07:31 -0500 Subject: [PATCH 164/527] Simplify import --- tests/models.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/models.py b/tests/models.py index 199fdc07..1aa55e49 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,9 +1,7 @@ from django.db import models from imagekit.models import ImageSpecField -from imagekit.processors import Adjust -from imagekit.processors import ResizeToFill -from imagekit.processors import SmartCrop +from imagekit.processors import Adjust, ResizeToFill, SmartCrop class Photo(models.Model): From 234082e63cba8b86066d63554b85b9f3d594d411 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:34:29 -0500 Subject: [PATCH 165/527] Extract generate() util, to make files Django likes --- imagekit/files.py | 15 +++------------ imagekit/utils.py | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index b4efd845..1dd8976a 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -3,10 +3,9 @@ from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode import os -from tempfile import NamedTemporaryFile from .signals import before_access from .utils import (format_to_mimetype, extension_to_mimetype, get_logger, - get_singleton) + get_singleton, generate) class BaseIKFile(File): @@ -116,17 +115,9 @@ def validate(self): def generate(self): # Generate the file - content = self.generator.generate() + content = generate(self.generator) - # If the file doesn't have a name, Django will raise an Exception while - # trying to save it, so we create a named temporary file. - if not getattr(content, 'name', None): - f = NamedTemporaryFile() - f.write(content.read()) - f.seek(0) - content = f - - actual_name = self.storage.save(self.name, File(content)) + actual_name = self.storage.save(self.name, content) if actual_name != self.name: get_logger().warning('The storage backend %s did not save the file' diff --git a/imagekit/utils.py b/imagekit/utils.py index e6c29434..82a2c023 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -2,9 +2,11 @@ import os import mimetypes import sys +from tempfile import NamedTemporaryFile import types from django.core.exceptions import ImproperlyConfigured +from django.core.files import File from django.db.models.loading import cache from django.utils.functional import wraps from django.utils.importlib import import_module @@ -401,3 +403,22 @@ def __init__(self, source): getattr(field_file, 'instance', None), getattr(getattr(field_file, 'field', None), 'attname', None), ) + + +def generate(generator): + """ + Calls the ``generate()`` method of a generator instance, and then wraps the + result in a Django File object so Django knows how to save it. + + """ + content = generator.generate() + + # If the file doesn't have a name, Django will raise an Exception while + # trying to save it, so we create a named temporary file. + if not getattr(content, 'name', None): + f = NamedTemporaryFile() + f.write(content.read()) + f.seek(0) + content = f + + return File(content) From c6f2c2e7a7377eec830e30680ce69a23c5e1c89c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:35:57 -0500 Subject: [PATCH 166/527] Add test for ProcessedImageField --- tests/models.py | 6 ++++++ tests/test_fields.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/test_fields.py diff --git a/tests/models.py b/tests/models.py index 1aa55e49..0b997ea9 100644 --- a/tests/models.py +++ b/tests/models.py @@ -1,5 +1,6 @@ from django.db import models +from imagekit.models import ProcessedImageField from imagekit.models import ImageSpecField from imagekit.processors import Adjust, ResizeToFill, SmartCrop @@ -16,6 +17,11 @@ class Photo(models.Model): format='JPEG', options={'quality': 90}) +class ProcessedImageFieldModel(models.Model): + processed = ProcessedImageField([SmartCrop(50, 50)], format='JPEG', + options={'quality': 90}, upload_to='p') + + class AbstractImageModel(models.Model): original_image = models.ImageField(upload_to='photos') abstract_class_spec = ImageSpecField() diff --git a/tests/test_fields.py b/tests/test_fields.py new file mode 100644 index 00000000..ee7301c5 --- /dev/null +++ b/tests/test_fields.py @@ -0,0 +1,15 @@ +from django.core.files.base import File +from nose.tools import eq_ +from . import imagespecs # noqa +from .models import ProcessedImageFieldModel +from .utils import get_image_file + + +def test_model_processedimagefield(): + instance = ProcessedImageFieldModel() + file = File(get_image_file()) + instance.processed.save('whatever.jpeg', file) + instance.save() + + eq_(instance.processed.width, 50) + eq_(instance.processed.height, 50) From 84b30e990fdb6a24aa48f8d36b998d2df8b07b89 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:37:00 -0500 Subject: [PATCH 167/527] Fix imagekit.models.fields.ProcessedImageField --- imagekit/models/fields/files.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/models/fields/files.py b/imagekit/models/fields/files.py index 26037fda..0fbbad63 100644 --- a/imagekit/models/fields/files.py +++ b/imagekit/models/fields/files.py @@ -1,13 +1,13 @@ from django.db.models.fields.files import ImageFieldFile import os -from ...utils import suggest_extension +from ...utils import suggest_extension, generate class ProcessedImageFieldFile(ImageFieldFile): def save(self, name, content, save=True): filename, ext = os.path.splitext(name) - spec = self.field.get_spec() # TODO: What "hints"? + spec = self.field.get_spec(source=content) ext = suggest_extension(name, spec.format) new_name = '%s%s' % (filename, ext) - content = spec.apply(content, new_name) + content = generate(spec) return super(ProcessedImageFieldFile, self).save(new_name, content, save) From f4917ab7ca267c446420209b98812c5ae8b59d55 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:39:14 -0500 Subject: [PATCH 168/527] Clean up util method --- tests/utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 1a4e3fcc..2763f8ff 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,7 +1,7 @@ from bs4 import BeautifulSoup import os from django.conf import settings -from django.core.files.base import ContentFile +from django.core.files import File from django.template import Context, Template from imagekit.lib import Image, StringIO import pickle @@ -26,10 +26,8 @@ def create_image(): def create_instance(model_class, image_name): instance = model_class() - img = get_image_file() - file = ContentFile(img.read()) - instance.original_image = file - instance.original_image.save(image_name, file) + img = File(get_image_file()) + instance.original_image.save(image_name, img) instance.save() img.close() return instance From a8855d4c27ce0df8cf8c0b40d2c1c368b2befebe Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Wed, 23 Jan 2013 22:46:57 -0500 Subject: [PATCH 169/527] Change spec/source registry to generator/cacheable --- imagekit/generatorlibrary.py | 2 +- imagekit/imagecache/strategies.py | 12 +- .../management/commands/warmimagecache.py | 34 ++--- imagekit/models/fields/__init__.py | 4 +- imagekit/registry.py | 116 +++++++++--------- imagekit/signals.py | 6 +- imagekit/specs/__init__.py | 2 +- imagekit/specs/sourcegroups.py | 18 +-- tests/imagespecs.py | 4 +- 9 files changed, 104 insertions(+), 94 deletions(-) diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index bd9da9a6..977e960d 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -10,4 +10,4 @@ def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): super(Thumbnail, self).__init__(**kwargs) -register.spec('ik:thumbnail', Thumbnail) +register.generator('ik:thumbnail', Thumbnail) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index 630b77cb..a0b8f763 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -14,19 +14,19 @@ def before_access(self, file): class Optimistic(object): """ - A caching strategy that acts immediately when the source file chages and - assumes that the cache files will not be removed (i.e. doesn't revalidate - on access). + A caching strategy that acts immediately when the cacheable file changes + and assumes that the cache files will not be removed (i.e. doesn't + revalidate on access). """ - def on_source_created(self, file): + def on_cacheable_created(self, file): validate_now(file) - def on_source_deleted(self, file): + def on_cacheable_deleted(self, file): clear_now(file) - def on_source_changed(self, file): + def on_cacheable_changed(self, file): validate_now(file) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 6c9822dd..42a005d3 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -1,35 +1,35 @@ from django.core.management.base import BaseCommand import re from ...files import GeneratedImageCacheFile -from ...registry import generator_registry, source_group_registry +from ...registry import generator_registry, cacheable_registry class Command(BaseCommand): - help = ('Warm the image cache for the specified specs (or all specs if none' - ' was provided). Simple wildcard matching (using asterisks) is' - ' supported.') - args = '[spec_ids]' + help = ('Warm the image cache for the specified generators' + ' (or all generators if none was provided).' + ' Simple wildcard matching (using asterisks) is supported.') + args = '[generator_ids]' def handle(self, *args, **options): - specs = generator_registry.get_ids() + generators = generator_registry.get_ids() if args: patterns = self.compile_patterns(args) - specs = (id for id in specs if any(p.match(id) for p in patterns)) + generators = (id for id in generators if any(p.match(id) for p in patterns)) - for spec_id in specs: - self.stdout.write('Validating spec: %s\n' % spec_id) - for source_group in source_group_registry.get(spec_id): - for source in source_group.files(): - if source: - spec = generator_registry.get(spec_id, source=source) # TODO: HINTS! (Probably based on source, so this will need to be moved into loop below.) - self.stdout.write(' %s\n' % source) + for generator_id in generators: + self.stdout.write('Validating generator: %s\n' % generator_id) + for cacheables in cacheable_registry.get(generator_id): + for cacheable in cacheables.files(): + if cacheable: + generator = generator_registry.get(generator_id, cacheable=cacheable) # TODO: HINTS! (Probably based on cacheable, so this will need to be moved into loop below.) + self.stdout.write(' %s\n' % cacheable) try: # TODO: Allow other validation actions through command option - GeneratedImageCacheFile(spec).validate() + GeneratedImageCacheFile(generator).validate() except Exception, err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) - def compile_patterns(self, spec_ids): - return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in spec_ids] + def compile_patterns(self, generator_ids): + return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in generator_ids] diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 131ff332..449faac5 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -45,8 +45,8 @@ def contribute_to_class(self, cls, name): self.set_spec_id(cls, name) # Add the model and field as a source for this spec id - register.sources(self.spec_id, - [ImageFieldSourceGroup(cls, self.source)]) + register.cacheables(self.spec_id, + ImageFieldSourceGroup(cls, self.source)) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/registry.py b/imagekit/registry.py index 8d082cdb..93e491fa 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,11 +1,11 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import (before_access, source_created, source_changed, - source_deleted) +from .signals import (before_access, cacheable_created, cacheable_changed, + cacheable_deleted) class GeneratorRegistry(object): """ - An object for registering generators (specs). This registry provides + An object for registering generators. This registry provides a convenient way for a distributable app to define default generators without locking the users of the app into it. @@ -15,7 +15,7 @@ def __init__(self): def register(self, id, generator): if id in self._generators: - raise AlreadyRegistered('The spec or generator with id %s is' + raise AlreadyRegistered('The generator with id %s is' ' already registered' % id) self._generators[id] = generator @@ -24,14 +24,14 @@ def unregister(self, id, generator): try: del self._generators[id] except KeyError: - raise NotRegistered('The spec or generator with id %s is not' + raise NotRegistered('The generator with id %s is not' ' registered' % id) def get(self, id, **kwargs): try: generator = self._generators[id] except KeyError: - raise NotRegistered('The spec or generator with id %s is not' + raise NotRegistered('The generator with id %s is not' ' registered' % id) if callable(generator): return generator(**kwargs) @@ -42,108 +42,114 @@ def get_ids(self): return self._generators.keys() -class SourceGroupRegistry(object): +class CacheableRegistry(object): """ - An object for registering source groups with specs. The two are + An object for registering cacheables with generators. The two are associated with each other via a string id. We do this (as opposed to - associating them directly by, for example, putting a ``source_groups`` - attribute on specs) so that specs can be overridden without losing the - associated sources. That way, a distributable app can define its own - specs without locking the users of the app into it. + associating them directly by, for example, putting a ``cacheables`` + attribute on generators) so that generators can be overridden without + losing the associated cacheables. That way, a distributable app can define + its own generators without locking the users of the app into it. """ _signals = [ - source_created, - source_changed, - source_deleted, + cacheable_created, + cacheable_changed, + cacheable_deleted, ] def __init__(self): - self._source_groups = {} + self._cacheables = {} for signal in self._signals: - signal.connect(self.source_group_receiver) + signal.connect(self.cacheable_receiver) before_access.connect(self.before_access_receiver) - def register(self, spec_id, source_groups): + def register(self, generator_id, cacheables): """ - Associates source groups with a spec id + Associates cacheables with a generator id """ - for source_group in source_groups: - if source_group not in self._source_groups: - self._source_groups[source_group] = set() - self._source_groups[source_group].add(spec_id) + for cacheable in cacheables: + if cacheable not in self._cacheables: + self._cacheables[cacheable] = set() + self._cacheables[cacheable].add(generator_id) - def unregister(self, spec_id, source_groups): + def unregister(self, generator_id, cacheables): """ - Disassociates sources with a spec id + Disassociates cacheables with a generator id """ - for source_group in source_groups: + for cacheable in cacheables: try: - self._source_groups[source_group].remove(spec_id) + self._cacheables[cacheable].remove(generator_id) except KeyError: continue - def get(self, spec_id): - return [source_group for source_group in self._source_groups - if spec_id in self._source_groups[source_group]] + def get(self, generator_id): + return [cacheable for cacheable in self._cacheables + if generator_id in self._cacheables[cacheable]] - def before_access_receiver(self, sender, generator, file, **kwargs): - generator.image_cache_strategy.invoke_callback('before_access', file) + def before_access_receiver(self, sender, generator, cacheable, **kwargs): + generator.image_cache_strategy.invoke_callback('before_access', cacheable) - def source_group_receiver(self, sender, source, signal, info, **kwargs): + def cacheable_receiver(self, sender, cacheable, signal, info, **kwargs): """ - Redirects signals dispatched on sources to the appropriate specs. + Redirects signals dispatched on cacheables + to the appropriate generators. """ - source_group = sender - if source_group not in self._source_groups: + cacheable = sender + if cacheable not in self._cacheables: return - for spec in (generator_registry.get(id, source=source, **info) - for id in self._source_groups[source_group]): + for generator in (generator_registry.get(id, cacheable=cacheable, **info) + for id in self._cacheables[cacheable]): event_name = { - source_created: 'source_created', - source_changed: 'source_changed', - source_deleted: 'source_deleted', + cacheable_created: 'cacheable_created', + cacheable_changed: 'cacheable_changed', + cacheable_deleted: 'cacheable_deleted', } - spec._handle_source_event(event_name, source) + generator._handle_cacheable_event(event_name, cacheable) class Register(object): """ - Register specs and sources. + Register generators and cacheables. """ - def spec(self, id, spec=None): - if spec is None: + def generator(self, id, generator=None): + if generator is None: # Return a decorator def decorator(cls): - self.spec(id, cls) + self.generator(id, cls) return cls return decorator - generator_registry.register(id, spec) + generator_registry.register(id, generator) - def sources(self, spec_id, sources): - source_group_registry.register(spec_id, sources) + # iterable that returns kwargs or callable that returns iterable of kwargs + def cacheables(self, generator_id, cacheables): + if callable(cacheables): + cacheables = cacheables() + cacheable_registry.register(generator_id, cacheables) class Unregister(object): """ - Unregister specs and sources. + Unregister generators and cacheables. """ - def spec(self, id, spec): - generator_registry.unregister(id, spec) + def generator(self, id, generator): + generator_registry.unregister(id, generator) - def sources(self, spec_id, sources): - source_group_registry.unregister(spec_id, sources) + def cacheables(self, generator_id, cacheables): + if callable(cacheables): + cacheables = cacheables() + cacheable_registry.unregister(generator_id, cacheables) generator_registry = GeneratorRegistry() -source_group_registry = SourceGroupRegistry() +cacheable_registry = CacheableRegistry() register = Register() unregister = Unregister() diff --git a/imagekit/signals.py b/imagekit/signals.py index 4c7aefad..97a9d9c0 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,6 +1,6 @@ from django.dispatch import Signal before_access = Signal() -source_created = Signal(providing_args=[]) -source_changed = Signal() -source_deleted = Signal() +cacheable_created = Signal(providing_args=[]) +cacheable_changed = Signal() +cacheable_deleted = Signal() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 9bfab2cb..015d4a6a 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -228,7 +228,7 @@ def set_spec_id(self, id): """ self.spec_id = id - register.spec(id, self._original_spec) + register.generator(id, self._original_spec) def get_spec(self, **kwargs): """ diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index b36b211b..6bd1eede 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -1,6 +1,6 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..signals import source_created, source_changed, source_deleted +from ..signals import cacheable_created, cacheable_changed, cacheable_deleted def ik_model_receiver(fn): @@ -58,23 +58,25 @@ def get_field_dict(self, instance): src in self._source_groups if src.model_class is instance.__class__) @ik_model_receiver - def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): + def post_save_receiver(self, sender, instance=None, created=False, + raw=False, **kwargs): if not raw: self.init_instance(instance) old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(source_created, file, sender, instance, - attname) + self.dispatch_signal(cacheable_created, file, sender, + instance, attname) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, file, sender, instance, - attname) + self.dispatch_signal(cacheable_changed, file, sender, + instance, attname) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance).items(): - self.dispatch_signal(source_deleted, file, sender, instance, attname) + self.dispatch_signal(cacheable_deleted, file, sender, instance, + attname) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): @@ -119,5 +121,7 @@ def files(self): for instance in self.model_class.objects.all(): yield getattr(instance, self.image_field) + def __call__(self): + return self.files() signal_router = ModelSignalRouter() diff --git a/tests/imagespecs.py b/tests/imagespecs.py index 06d2dab1..11e87b37 100644 --- a/tests/imagespecs.py +++ b/tests/imagespecs.py @@ -12,5 +12,5 @@ def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): super(ResizeTo1PixelSquare, self).__init__(**kwargs) -register.spec('testspec', TestSpec) -register.spec('1pxsq', ResizeTo1PixelSquare) +register.generator('testspec', TestSpec) +register.generator('1pxsq', ResizeTo1PixelSquare) From b45a22abe6f472b6fc875b442fdc90e3a4330284 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:54:08 -0500 Subject: [PATCH 170/527] Add test for imagekit.forms.fields.ProcessedImageField --- tests/models.py | 4 ++++ tests/test_fields.py | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/models.py b/tests/models.py index 0b997ea9..17e887be 100644 --- a/tests/models.py +++ b/tests/models.py @@ -5,6 +5,10 @@ from imagekit.processors import Adjust, ResizeToFill, SmartCrop +class ImageModel(models.Model): + image = models.ImageField(upload_to='b') + + class Photo(models.Model): original_image = models.ImageField(upload_to='photos') diff --git a/tests/test_fields.py b/tests/test_fields.py index ee7301c5..bce294fc 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -1,7 +1,11 @@ +from django import forms from django.core.files.base import File +from django.core.files.uploadedfile import SimpleUploadedFile +from imagekit import forms as ikforms +from imagekit.processors import SmartCrop from nose.tools import eq_ from . import imagespecs # noqa -from .models import ProcessedImageFieldModel +from .models import ProcessedImageFieldModel, ImageModel from .utils import get_image_file @@ -13,3 +17,20 @@ def test_model_processedimagefield(): eq_(instance.processed.width, 50) eq_(instance.processed.height, 50) + + +def test_form_processedimagefield(): + class TestForm(forms.ModelForm): + image = ikforms.ProcessedImageField(spec_id='tests:testform_image', + processors=[SmartCrop(50, 50)], format='JPEG') + + class Meta: + model = ImageModel + + upload_file = get_image_file() + file_dict = {'image': SimpleUploadedFile('abc.jpg', upload_file.read())} + form = TestForm({}, file_dict) + instance = form.save() + + eq_(instance.image.width, 50) + eq_(instance.image.height, 50) From c202234e827b294f7a7d418d868f0c6f95715929 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 23 Jan 2013 22:54:25 -0500 Subject: [PATCH 171/527] Fix imagekit.forms.fields.ProcessedImageField --- imagekit/forms/fields.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index 40bb5b52..903f6aec 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -1,5 +1,6 @@ from django.forms import ImageField from ..specs import SpecHost +from ..utils import generate class ProcessedImageField(ImageField, SpecHost): @@ -22,7 +23,7 @@ def clean(self, data, initial=None): data = super(ProcessedImageField, self).clean(data, initial) if data: - spec = self.get_spec() # HINTS?!?!?!?!?! - data = spec.apply(data, data.name) + spec = self.get_spec(source=data) + data = generate(spec) return data From eb9089e0c8966adea727c2bb9460b371360c79b1 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Thu, 24 Jan 2013 00:04:43 -0500 Subject: [PATCH 172/527] Register cacheables as generators instead of items --- .../management/commands/warmimagecache.py | 21 +++++++-------- imagekit/registry.py | 26 ++++++++----------- imagekit/specs/sourcegroups.py | 7 ++--- 3 files changed, 23 insertions(+), 31 deletions(-) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index 42a005d3..dfe5d469 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -19,17 +19,16 @@ def handle(self, *args, **options): for generator_id in generators: self.stdout.write('Validating generator: %s\n' % generator_id) - for cacheables in cacheable_registry.get(generator_id): - for cacheable in cacheables.files(): - if cacheable: - generator = generator_registry.get(generator_id, cacheable=cacheable) # TODO: HINTS! (Probably based on cacheable, so this will need to be moved into loop below.) - self.stdout.write(' %s\n' % cacheable) - try: - # TODO: Allow other validation actions through command option - GeneratedImageCacheFile(generator).validate() - except Exception, err: - # TODO: How should we handle failures? Don't want to error, but should call it out more than this. - self.stdout.write(' FAILED: %s\n' % err) + for kwargs in cacheable_registry.get(generator_id): + if kwargs: + generator = generator_registry.get(generator_id, **kwargs) # TODO: HINTS! (Probably based on cacheable, so this will need to be moved into loop below.) + self.stdout.write(' %s\n' % generator) + try: + # TODO: Allow other validation actions through command option + GeneratedImageCacheFile(generator).validate() + except Exception, err: + # TODO: How should we handle failures? Don't want to error, but should call it out more than this. + self.stdout.write(' FAILED: %s\n' % err) def compile_patterns(self, generator_ids): return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in generator_ids] diff --git a/imagekit/registry.py b/imagekit/registry.py index 93e491fa..258f2524 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -70,25 +70,25 @@ def register(self, generator_id, cacheables): Associates cacheables with a generator id """ - for cacheable in cacheables: - if cacheable not in self._cacheables: - self._cacheables[cacheable] = set() - self._cacheables[cacheable].add(generator_id) + if cacheables not in self._cacheables: + self._cacheables[cacheables] = set() + self._cacheables[cacheables].add(generator_id) def unregister(self, generator_id, cacheables): """ Disassociates cacheables with a generator id """ - for cacheable in cacheables: - try: - self._cacheables[cacheable].remove(generator_id) - except KeyError: - continue + try: + self._cacheables[cacheables].remove(generator_id) + except KeyError: + pass def get(self, generator_id): - return [cacheable for cacheable in self._cacheables - if generator_id in self._cacheables[cacheable]] + for k, v in self._cacheables.items(): + if generator_id in v: + for cacheable in k(): + yield cacheable def before_access_receiver(self, sender, generator, cacheable, **kwargs): generator.image_cache_strategy.invoke_callback('before_access', cacheable) @@ -130,8 +130,6 @@ def decorator(cls): # iterable that returns kwargs or callable that returns iterable of kwargs def cacheables(self, generator_id, cacheables): - if callable(cacheables): - cacheables = cacheables() cacheable_registry.register(generator_id, cacheables) @@ -144,8 +142,6 @@ def generator(self, id, generator): generator_registry.unregister(id, generator) def cacheables(self, generator_id, cacheables): - if callable(cacheables): - cacheables = cacheables() cacheable_registry.unregister(generator_id, cacheables) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 6bd1eede..04c30c36 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -117,11 +117,8 @@ def __init__(self, model_class, image_field): self.image_field = image_field signal_router.add(self) - def files(self): - for instance in self.model_class.objects.all(): - yield getattr(instance, self.image_field) - def __call__(self): - return self.files() + for instance in self.model_class.objects.all(): + yield {'source': getattr(instance, self.image_field)} signal_router = ModelSignalRouter() From a3e9a080d44b07c78dd00afb8b5a6a2ec9cb103c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 28 Jan 2013 21:07:35 -0500 Subject: [PATCH 173/527] Revert signal names --- imagekit/imagecache/strategies.py | 6 +++--- imagekit/registry.py | 16 ++++++++-------- imagekit/signals.py | 6 +++--- imagekit/specs/sourcegroups.py | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index a0b8f763..56efbd7e 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -20,13 +20,13 @@ class Optimistic(object): """ - def on_cacheable_created(self, file): + def on_source_created(self, file): validate_now(file) - def on_cacheable_deleted(self, file): + def on_source_deleted(self, file): clear_now(file) - def on_cacheable_changed(self, file): + def on_source_changed(self, file): validate_now(file) diff --git a/imagekit/registry.py b/imagekit/registry.py index 258f2524..6f48f9ca 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,6 +1,6 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import (before_access, cacheable_created, cacheable_changed, - cacheable_deleted) +from .signals import (before_access, source_created, source_changed, + source_deleted) class GeneratorRegistry(object): @@ -54,9 +54,9 @@ class CacheableRegistry(object): """ _signals = [ - cacheable_created, - cacheable_changed, - cacheable_deleted, + source_created, + source_changed, + source_deleted, ] def __init__(self): @@ -106,9 +106,9 @@ def cacheable_receiver(self, sender, cacheable, signal, info, **kwargs): for generator in (generator_registry.get(id, cacheable=cacheable, **info) for id in self._cacheables[cacheable]): event_name = { - cacheable_created: 'cacheable_created', - cacheable_changed: 'cacheable_changed', - cacheable_deleted: 'cacheable_deleted', + source_created: 'source_created', + source_changed: 'source_changed', + source_deleted: 'source_deleted', } generator._handle_cacheable_event(event_name, cacheable) diff --git a/imagekit/signals.py b/imagekit/signals.py index 97a9d9c0..4c7aefad 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,6 +1,6 @@ from django.dispatch import Signal before_access = Signal() -cacheable_created = Signal(providing_args=[]) -cacheable_changed = Signal() -cacheable_deleted = Signal() +source_created = Signal(providing_args=[]) +source_changed = Signal() +source_deleted = Signal() diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 04c30c36..825276e4 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -1,6 +1,6 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..signals import cacheable_created, cacheable_changed, cacheable_deleted +from ..signals import source_created, source_changed, source_deleted def ik_model_receiver(fn): @@ -66,16 +66,16 @@ def post_save_receiver(self, sender, instance=None, created=False, new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(cacheable_created, file, sender, + self.dispatch_signal(source_created, file, sender, instance, attname) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(cacheable_changed, file, sender, + self.dispatch_signal(source_changed, file, sender, instance, attname) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance).items(): - self.dispatch_signal(cacheable_deleted, file, sender, instance, + self.dispatch_signal(source_deleted, file, sender, instance, attname) @ik_model_receiver From 5b4456431814b9a892b97547ea3c3c29e17b41fb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 28 Jan 2013 21:31:38 -0500 Subject: [PATCH 174/527] Add LazyGeneratedImageCacheFile --- imagekit/files.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/imagekit/files.py b/imagekit/files.py index 1dd8976a..c025af34 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -2,7 +2,9 @@ from django.core.files.base import ContentFile, File from django.core.files.images import ImageFile from django.utils.encoding import smart_str, smart_unicode +from django.utils.functional import LazyObject import os +from .registry import generator_registry from .signals import before_access from .utils import (format_to_mimetype, extension_to_mimetype, get_logger, get_singleton, generate) @@ -158,3 +160,14 @@ def __str__(self): def __unicode__(self): return smart_unicode(self.file.name or u'') + + +class LazyGeneratedImageCacheFile(LazyObject): + def __init__(self, generator_id, *args, **kwargs): + super(LazyGeneratedImageCacheFile, self).__init__() + + def setup(): + generator = generator_registry.get(generator_id, *args, **kwargs) + self._wrapped = GeneratedImageCacheFile(generator) + + self.__dict__['_setup'] = setup From 3931b552a0924fa34b3333c4e6605d81c9f83204 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 01:40:00 -0500 Subject: [PATCH 175/527] Separate source groups and cacheables. This allows a sensible specialized interface for source groups, but also for ImageKit to interact with specs using the generalized image generator interface. --- imagekit/files.py | 2 +- imagekit/imagecache/strategies.py | 5 -- imagekit/models/fields/__init__.py | 4 +- imagekit/registry.py | 104 ++++++++++++++++++++--------- imagekit/signals.py | 6 +- imagekit/specs/__init__.py | 6 -- imagekit/specs/sourcegroups.py | 102 +++++++++++++++++++--------- imagekit/utils.py | 7 ++ 8 files changed, 157 insertions(+), 79 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index c025af34..150cfa08 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -103,7 +103,7 @@ def __init__(self, generator, name=None, storage=None, image_cache_backend=None) super(GeneratedImageCacheFile, self).__init__(storage=storage) def _require_file(self): - before_access.send(sender=self, generator=self.generator, file=self) + before_access.send(sender=self, file=self) return super(GeneratedImageCacheFile, self)._require_file() def clear(self): diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index 56efbd7e..4a3d6189 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -46,11 +46,6 @@ def __init__(self, strategy): strategy = strategy() self._wrapped = strategy - def invoke_callback(self, name, *args, **kwargs): - func = getattr(self._wrapped, name, None) - if func: - func(*args, **kwargs) - def __unicode__(self): return unicode(self._wrapped) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 449faac5..2aea3ca1 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -45,8 +45,8 @@ def contribute_to_class(self, cls, name): self.set_spec_id(cls, name) # Add the model and field as a source for this spec id - register.cacheables(self.spec_id, - ImageFieldSourceGroup(cls, self.source)) + register.source_group(self.spec_id, + ImageFieldSourceGroup(cls, self.source)) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/registry.py b/imagekit/registry.py index 6f48f9ca..d74f6b10 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,6 +1,6 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import (before_access, source_created, source_changed, - source_deleted) +from .signals import before_access, source_created, source_changed, source_deleted +from .utils import call_strategy_method class GeneratorRegistry(object): @@ -12,6 +12,7 @@ class GeneratorRegistry(object): """ def __init__(self): self._generators = {} + before_access.connect(self.before_access_receiver) def register(self, id, generator): if id in self._generators: @@ -41,6 +42,67 @@ def get(self, id, **kwargs): def get_ids(self): return self._generators.keys() + def before_access_receiver(self, sender, file, **kwargs): + generator = file.generator + if generator in self._generators.values(): + # Only invoke the strategy method for registered generators. + call_strategy_method(generator, 'before_access', file=file) + + +class SourceGroupRegistry(object): + """ + The source group registry is responsible for listening to source_* signals + on source groups, and relaying them to the image cache strategies of the + appropriate generators. + + In addition, registering a new source group also registers its cacheables + generator with the cacheable registry. + + """ + _signals = { + source_created: 'on_source_created', + source_changed: 'on_source_changed', + source_deleted: 'on_source_deleted', + } + + def __init__(self): + self._source_groups = {} + for signal in self._signals.keys(): + signal.connect(self.source_group_receiver) + + def register(self, generator_id, source_group): + from .specs.sourcegroups import SourceGroupCacheablesGenerator + generator_ids = self._source_groups.setdefault(source_group, set()) + generator_ids.add(generator_id) + cacheable_registry.register(generator_id, + SourceGroupCacheablesGenerator(source_group, generator_id)) + + def unregister(self, generator_id, source_group): + from .specs.sourcegroups import SourceGroupCacheablesGenerator + generator_ids = self._source_groups.setdefault(source_group, set()) + if generator_id in generator_ids: + generator_ids.remove(generator_id) + cacheable_registry.unregister(generator_id, + SourceGroupCacheablesGenerator(source_group, generator_id)) + + def source_group_receiver(self, sender, source, signal, **kwargs): + """ + Relay source group signals to the appropriate spec strategy. + + """ + source_group = sender + + # Ignore signals from unregistered groups. + if source_group not in self._source_groups: + return + + specs = [generator_registry.get(id, source=source) for id in + self._source_groups[source_group]] + callback_name = self._signals[signal] + + for spec in specs: + call_strategy_method(spec, callback_name, file=source) + class CacheableRegistry(object): """ @@ -53,17 +115,8 @@ class CacheableRegistry(object): """ - _signals = [ - source_created, - source_changed, - source_deleted, - ] - def __init__(self): self._cacheables = {} - for signal in self._signals: - signal.connect(self.cacheable_receiver) - before_access.connect(self.before_access_receiver) def register(self, generator_id, cacheables): """ @@ -90,28 +143,6 @@ def get(self, generator_id): for cacheable in k(): yield cacheable - def before_access_receiver(self, sender, generator, cacheable, **kwargs): - generator.image_cache_strategy.invoke_callback('before_access', cacheable) - - def cacheable_receiver(self, sender, cacheable, signal, info, **kwargs): - """ - Redirects signals dispatched on cacheables - to the appropriate generators. - - """ - cacheable = sender - if cacheable not in self._cacheables: - return - - for generator in (generator_registry.get(id, cacheable=cacheable, **info) - for id in self._cacheables[cacheable]): - event_name = { - source_created: 'source_created', - source_changed: 'source_changed', - source_deleted: 'source_deleted', - } - generator._handle_cacheable_event(event_name, cacheable) - class Register(object): """ @@ -132,6 +163,9 @@ def decorator(cls): def cacheables(self, generator_id, cacheables): cacheable_registry.register(generator_id, cacheables) + def source_group(self, generator_id, source_group): + source_group_registry.register(generator_id, source_group) + class Unregister(object): """ @@ -144,8 +178,12 @@ def generator(self, id, generator): def cacheables(self, generator_id, cacheables): cacheable_registry.unregister(generator_id, cacheables) + def source_group(self, generator_id, source_group): + source_group_registry.unregister(generator_id, source_group) + generator_registry = GeneratorRegistry() cacheable_registry = CacheableRegistry() +source_group_registry = SourceGroupRegistry() register = Register() unregister = Unregister() diff --git a/imagekit/signals.py b/imagekit/signals.py index 4c7aefad..c01e30e7 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,6 +1,10 @@ from django.dispatch import Signal + +# "Cacheables" (cache file) signals before_access = Signal() -source_created = Signal(providing_args=[]) + +# Source group signals +source_created = Signal() source_changed = Signal() source_deleted = Signal() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 01c7131a..7b928455 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -3,7 +3,6 @@ from hashlib import md5 import os import pickle -from ..files import GeneratedImageCacheFile from ..imagecache.backends import get_default_image_cache_backend from ..imagecache.strategies import StrategyWrapper from ..processors import ProcessorPipeline @@ -43,11 +42,6 @@ def __init__(self): def generate(self): raise NotImplementedError - # TODO: I don't like this interface. Is there a standard Python one? pubsub? - def _handle_source_event(self, event_name, source): - file = GeneratedImageCacheFile(self) - self.image_cache_strategy.invoke_callback('on_%s' % event_name, file) - class ImageSpec(BaseImageSpec): """ diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 825276e4..3c23d642 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -1,12 +1,26 @@ +""" +Source groups are the means by which image spec sources are identified. They +have two responsibilities: + +1. To dispatch ``source_created``, ``source_changed``, and ``source_deleted`` + signals. (These will be relayed to the corresponding specs' image cache + strategies.) +2. To provide the source files that they represent, via a generator method named + ``files()``. (This is used by the warmimagecache management command for + "pre-caching" image files.) + +""" + from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps +from ..files import LazyGeneratedImageCacheFile from ..signals import source_created, source_changed, source_deleted def ik_model_receiver(fn): """ A method decorator that filters out signals coming from models that don't - have fields that function as ImageFieldSourceGroup + have fields that function as ImageFieldSourceGroup sources. """ @wraps(fn) @@ -18,8 +32,15 @@ def receiver(self, sender, **kwargs): class ModelSignalRouter(object): """ - Handles signals dispatched by models and relays them to the spec source - groups that represent those models. + Normally, ``ImageFieldSourceGroup`` would be directly responsible for + watching for changes on the model field it represents. However, Django does + not dispatch events for abstract base classes. Therefore, we must listen for + the signals on all models and filter out those that aren't represented by + ``ImageFieldSourceGroup``s. This class encapsulates that functionality. + + Related: + https://github.com/jdriscoll/django-imagekit/issues/126 + https://code.djangoproject.com/ticket/9318 """ @@ -58,25 +79,23 @@ def get_field_dict(self, instance): src in self._source_groups if src.model_class is instance.__class__) @ik_model_receiver - def post_save_receiver(self, sender, instance=None, created=False, - raw=False, **kwargs): + def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): if not raw: self.init_instance(instance) old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): if created: - self.dispatch_signal(source_created, file, sender, - instance, attname) + self.dispatch_signal(source_created, file, sender, instance, + attname) elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, file, sender, - instance, attname) + self.dispatch_signal(source_changed, file, sender, instance, + attname) @ik_model_receiver def post_delete_receiver(self, sender, instance=None, **kwargs): for attname, file in self.get_field_dict(instance).items(): - self.dispatch_signal(source_deleted, file, sender, instance, - attname) + self.dispatch_signal(source_deleted, file, sender, instance, attname) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): @@ -91,34 +110,55 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): """ for source_group in self._source_groups: if source_group.model_class is model_class and source_group.image_field == attname: - info = dict( - source_group=source_group, - instance=instance, - field_name=attname, - ) - signal.send(sender=source_group, source=file, info=info) + signal.send(sender=source_group, source=file) class ImageFieldSourceGroup(object): - def __init__(self, model_class, image_field): - """ - Good design would dictate that this instance would be responsible for - watching for changes for the provided field. However, due to a bug in - Django, we can't do that without leaving abstract base models (which - don't trigger signals) in the lurch. So instead, we do all signal - handling through the signal router. - - Related: - https://github.com/jdriscoll/django-imagekit/issues/126 - https://code.djangoproject.com/ticket/9318 + """ + A source group that repesents a particular field across all instances of a + model. - """ + """ + def __init__(self, model_class, image_field): self.model_class = model_class self.image_field = image_field signal_router.add(self) - def __call__(self): + def files(self): + """ + A generator that returns the source files that this source group + represents; in this case, a particular field of every instance of a + particular model. + + """ for instance in self.model_class.objects.all(): - yield {'source': getattr(instance, self.image_field)} + yield getattr(instance, self.image_field) + + +class SourceGroupCacheablesGenerator(object): + """ + A cacheables generator for source groups. The purpose of this class is to + generate cacheables (cache files) from a source group. + + """ + def __init__(self, source_group, generator_id): + self.source_group = source_group + self.generator_id = generator_id + + def __eq__(self, other): + return (isinstance(other, self.__class__) + and self.__dict__ == other.__dict__) + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash((self.source_group, self.generator_id)) + + def __call__(self): + for source_file in self.source_group.files(): + yield LazyGeneratedImageCacheFile(self.generator_id, + source=source_file) + signal_router = ModelSignalRouter() diff --git a/imagekit/utils.py b/imagekit/utils.py index 82a2c023..adeb3779 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -422,3 +422,10 @@ def generate(generator): content = f return File(content) + + +def call_strategy_method(generator, method_name, *args, **kwargs): + strategy = getattr(generator, 'image_cache_strategy', None) + fn = getattr(strategy, method_name, None) + if fn is not None: + fn(*args, **kwargs) From ca4f090e63f7415905db8a71f8ae39ff00bb52a1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 01:48:06 -0500 Subject: [PATCH 176/527] Fix source callbacks on strategies --- imagekit/imagecache/strategies.py | 3 ++- imagekit/registry.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index 4a3d6189..cb7edd48 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -1,3 +1,4 @@ +from django.utils.functional import LazyObject from .actions import validate_now, clear_now from ..utils import get_singleton @@ -36,7 +37,7 @@ def __init__(self, callbacks): setattr(self, k, v) -class StrategyWrapper(object): +class StrategyWrapper(LazyObject): def __init__(self, strategy): if isinstance(strategy, basestring): strategy = get_singleton(strategy, 'image cache strategy') diff --git a/imagekit/registry.py b/imagekit/registry.py index d74f6b10..764ba247 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -90,6 +90,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): Relay source group signals to the appropriate spec strategy. """ + from .files import GeneratedImageCacheFile source_group = sender # Ignore signals from unregistered groups. @@ -101,7 +102,8 @@ def source_group_receiver(self, sender, source, signal, **kwargs): callback_name = self._signals[signal] for spec in specs: - call_strategy_method(spec, callback_name, file=source) + file = GeneratedImageCacheFile(spec) + call_strategy_method(spec, callback_name, file=file) class CacheableRegistry(object): From e48817a5ecbe72bb2f6e3b6c6d3d5dd44c9ee2d6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 01:53:23 -0500 Subject: [PATCH 177/527] Update warmimagecache to use new cacheable registry --- .../management/commands/warmimagecache.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index dfe5d469..b07c7ec9 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -1,6 +1,5 @@ from django.core.management.base import BaseCommand import re -from ...files import GeneratedImageCacheFile from ...registry import generator_registry, cacheable_registry @@ -19,16 +18,14 @@ def handle(self, *args, **options): for generator_id in generators: self.stdout.write('Validating generator: %s\n' % generator_id) - for kwargs in cacheable_registry.get(generator_id): - if kwargs: - generator = generator_registry.get(generator_id, **kwargs) # TODO: HINTS! (Probably based on cacheable, so this will need to be moved into loop below.) - self.stdout.write(' %s\n' % generator) - try: - # TODO: Allow other validation actions through command option - GeneratedImageCacheFile(generator).validate() - except Exception, err: - # TODO: How should we handle failures? Don't want to error, but should call it out more than this. - self.stdout.write(' FAILED: %s\n' % err) + for cacheable in cacheable_registry.get(generator_id): + self.stdout.write(' %s\n' % cacheable) + try: + # TODO: Allow other validation actions through command option + cacheable.validate() + except Exception, err: + # TODO: How should we handle failures? Don't want to error, but should call it out more than this. + self.stdout.write(' FAILED: %s\n' % err) def compile_patterns(self, generator_ids): return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in generator_ids] From e0ffb246ae8f253b511e31803d2dcd566a4b9bbb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 02:17:52 -0500 Subject: [PATCH 178/527] Always use colon as segment separator --- imagekit/models/fields/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 2aea3ca1..35c78da5 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -11,7 +11,7 @@ def set_spec_id(self, cls, name): # Generate a spec_id to register the spec with. The default spec id is # ":_" if not getattr(self, 'spec_id', None): - spec_id = (u'%s:%s_%s' % (cls._meta.app_label, + spec_id = (u'%s:%s:%s' % (cls._meta.app_label, cls._meta.object_name, name)).lower() # Register the spec with the id. This allows specs to be overridden From 54ca5da15d177291585f395ad08c89343e01931c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 02:18:21 -0500 Subject: [PATCH 179/527] Improve generator id pattern matching This behavior allows users to easy generate images by app, model, or field. --- .../management/commands/warmimagecache.py | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/warmimagecache.py index b07c7ec9..9f2a8c8d 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/warmimagecache.py @@ -4,9 +4,12 @@ class Command(BaseCommand): - help = ('Warm the image cache for the specified generators' - ' (or all generators if none was provided).' - ' Simple wildcard matching (using asterisks) is supported.') + help = ("""Warm the image cache for the specified generators (or all generators if +none was provided). Simple, fnmatch-like wildcards are allowed, with * +matching all characters within a segment, and ** matching across segments. +(Segments are separated with colons.) So, for example, "a:*:c" will match +"a:b:c", but not "a:b:x:c", whereas "a:**:c" will match both. Subsegments +are always matched, so "a" will match "a" as well as "a:b" and "a:b:c".""") args = '[generator_ids]' def handle(self, *args, **options): @@ -28,4 +31,16 @@ def handle(self, *args, **options): self.stdout.write(' FAILED: %s\n' % err) def compile_patterns(self, generator_ids): - return [re.compile('%s$' % '.*'.join(re.escape(part) for part in id.split('*'))) for id in generator_ids] + return [self.compile_pattern(id) for id in generator_ids] + + def compile_pattern(self, generator_id): + parts = re.split(r'(\*{1,2})', generator_id) + pattern = '' + for part in parts: + if part == '*': + pattern += '[^:]*' + elif part == '**': + pattern += '.*' + else: + pattern += re.escape(part) + return re.compile('^%s(:.*)?$' % pattern) From f0dbe32f7a9fb1781eba214c4eb92b9b9ff6f8f7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 29 Jan 2013 02:27:03 -0500 Subject: [PATCH 180/527] Fix pickling error --- imagekit/imagecache/strategies.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/imagekit/imagecache/strategies.py b/imagekit/imagecache/strategies.py index cb7edd48..28068f06 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/imagecache/strategies.py @@ -47,6 +47,12 @@ def __init__(self, strategy): strategy = strategy() self._wrapped = strategy + def __getstate__(self): + return {'_wrapped': self._wrapped} + + def __setstate__(self, state): + self._wrapped = state['_wrapped'] + def __unicode__(self): return unicode(self._wrapped) From 04aa72c1f9f8f7e84a0e5a6ef15fb7f74d81ecef Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 03:51:29 -0500 Subject: [PATCH 181/527] Rename cache things (it isn't cachine) https://twitter.com/alex_gaynor/statuses/257558176965206016 --- imagekit/conf.py | 6 +- imagekit/files.py | 53 ++++++------ .../{imagecache => generators}/__init__.py | 0 .../{imagecache => generators}/actions.py | 10 +-- imagekit/generators/filebackends.py | 64 +++++++++++++++ .../{imagecache => generators}/strategies.py | 19 ++--- imagekit/imagecache/backends.py | 82 ------------------- .../{warmimagecache.py => generateimages.py} | 21 ++--- imagekit/models/fields/__init__.py | 10 +-- imagekit/models/fields/utils.py | 4 +- imagekit/registry.py | 72 ++++++++-------- imagekit/signals.py | 2 +- imagekit/specs/__init__.py | 32 ++++---- imagekit/specs/sourcegroups.py | 13 ++- imagekit/templatetags/imagekit.py | 14 ++-- imagekit/utils.py | 2 +- 16 files changed, 189 insertions(+), 215 deletions(-) rename imagekit/{imagecache => generators}/__init__.py (100%) rename imagekit/{imagecache => generators}/actions.py (60%) create mode 100644 imagekit/generators/filebackends.py rename imagekit/{imagecache => generators}/strategies.py (68%) delete mode 100644 imagekit/imagecache/backends.py rename imagekit/management/commands/{warmimagecache.py => generateimages.py} (68%) diff --git a/imagekit/conf.py b/imagekit/conf.py index 288d3668..7eb3afc1 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,11 +3,11 @@ class ImageKitConf(AppConf): - DEFAULT_IMAGE_CACHE_BACKEND = 'imagekit.imagecache.backends.Simple' + DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generators.filebackends.Simple' CACHE_BACKEND = None - CACHE_DIR = 'CACHE/images' + GENERATED_FILE_DIR = 'generated/images' CACHE_PREFIX = 'imagekit:' - DEFAULT_IMAGE_CACHE_STRATEGY = 'imagekit.imagecache.strategies.JustInTime' + DEFAULT_IMAGE_GENERATOR_STRATEGY = 'imagekit.generators.strategies.JustInTime' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' def configure_cache_backend(self, value): diff --git a/imagekit/files.py b/imagekit/files.py index 150cfa08..9b07659d 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -72,48 +72,41 @@ def close(self): file.close() -class GeneratedImageCacheFile(BaseIKFile, ImageFile): +class GeneratedImageFile(BaseIKFile, ImageFile): """ - A cache file that represents the result of a generator. Creating an instance - of this class is not enough to trigger the creation of the cache file. In - fact, one of the main points of this class is to allow the creation of the - file to be deferred until the time that the image cache strategy requires - it. + A file that represents the result of a generator. Creating an instance of + this class is not enough to trigger the generation of the file. In fact, + one of the main points of this class is to allow the creation of the file + to be deferred until the time that the image generator strategy requires it. """ - def __init__(self, generator, name=None, storage=None, image_cache_backend=None): + def __init__(self, generator, name=None, storage=None, generatedfile_backend=None): """ :param generator: The object responsible for generating a new image. :param name: The filename :param storage: A Django storage object that will be used to save the file. - :param image_cache_backend: The object responsible for managing the - state of the cache file. + :param generatedfile_backend: The object responsible for managing the + state of the file. """ self.generator = generator - self.name = name or getattr(generator, 'cache_file_name', None) - storage = storage or getattr(generator, 'cache_file_storage', + self.name = name or getattr(generator, 'generatedfile_name', None) + storage = storage or getattr(generator, 'generatedfile_storage', None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') - self.image_cache_backend = image_cache_backend or getattr(generator, - 'image_cache_backend', None) + self.generatedfile_backend = generatedfile_backend or getattr(generator, + 'generatedfile_backend', None) - super(GeneratedImageCacheFile, self).__init__(storage=storage) + super(GeneratedImageFile, self).__init__(storage=storage) def _require_file(self): before_access.send(sender=self, file=self) - return super(GeneratedImageCacheFile, self)._require_file() + return super(GeneratedImageFile, self)._require_file() - def clear(self): - return self.image_cache_backend.clear(self) - - def invalidate(self): - return self.image_cache_backend.invalidate(self) - - def validate(self): - return self.image_cache_backend.validate(self) + def ensure_exists(self): + return self.generatedfile_backend.ensure_exists(self) def generate(self): # Generate the file @@ -126,11 +119,11 @@ def generate(self): ' with the requested name ("%s") and instead used' ' "%s". This may be because a file already existed with' ' the requested name. If so, you may have meant to call' - ' validate() instead of generate(), or there may be a' - ' race condition in the image cache backend %s. The' - ' saved file will not be used.' % (self.storage, + ' ensure_exists() instead of generate(), or there may be a' + ' race condition in the file backend %s. The saved file' + ' will not be used.' % (self.storage, self.name, actual_name, - self.image_cache_backend)) + self.generatedfile_backend)) class IKContentFile(ContentFile): @@ -162,12 +155,12 @@ def __unicode__(self): return smart_unicode(self.file.name or u'') -class LazyGeneratedImageCacheFile(LazyObject): +class LazyGeneratedImageFile(LazyObject): def __init__(self, generator_id, *args, **kwargs): - super(LazyGeneratedImageCacheFile, self).__init__() + super(LazyGeneratedImageFile, self).__init__() def setup(): generator = generator_registry.get(generator_id, *args, **kwargs) - self._wrapped = GeneratedImageCacheFile(generator) + self._wrapped = GeneratedImageFile(generator) self.__dict__['_setup'] = setup diff --git a/imagekit/imagecache/__init__.py b/imagekit/generators/__init__.py similarity index 100% rename from imagekit/imagecache/__init__.py rename to imagekit/generators/__init__.py diff --git a/imagekit/imagecache/actions.py b/imagekit/generators/actions.py similarity index 60% rename from imagekit/imagecache/actions.py rename to imagekit/generators/actions.py index b829a5fb..dc565761 100644 --- a/imagekit/imagecache/actions.py +++ b/imagekit/generators/actions.py @@ -1,5 +1,5 @@ -def validate_now(file): - file.validate() +def ensure_exists(file): + file.ensure_exists() try: @@ -7,15 +7,15 @@ def validate_now(file): except ImportError: pass else: - validate_now_task = task(validate_now) + ensure_exists_task = task(ensure_exists) -def deferred_validate(file): +def ensure_exists_deferred(file): try: import celery # NOQA except: raise ImportError("Deferred validation requires the the 'celery' library") - validate_now_task.delay(file) + ensure_exists_task.delay(file) def clear_now(file): diff --git a/imagekit/generators/filebackends.py b/imagekit/generators/filebackends.py new file mode 100644 index 00000000..b80aa8ef --- /dev/null +++ b/imagekit/generators/filebackends.py @@ -0,0 +1,64 @@ +from ..utils import get_singleton +from django.core.cache import get_cache +from django.core.exceptions import ImproperlyConfigured + + +def get_default_generatedfile_backend(): + """ + Get the default file backend. + + """ + from django.conf import settings + return get_singleton(settings.IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND, + 'file backend') + + +class InvalidFileBackendError(ImproperlyConfigured): + pass + + +class CachedFileBackend(object): + @property + def cache(self): + if not getattr(self, '_cache', None): + from django.conf import settings + self._cache = get_cache(settings.IMAGEKIT_CACHE_BACKEND) + return self._cache + + def get_key(self, file): + from django.conf import settings + return '%s%s-exists' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) + + def file_exists(self, file): + key = self.get_key(file) + exists = self.cache.get(key) + if exists is None: + exists = self._file_exists(file) + self.cache.set(key, exists) + return exists + + def ensure_exists(self, file): + if self.file_exists(file): + self.create(file) + self.cache.set(self.get_key(file), True) + + +class Simple(CachedFileBackend): + """ + The most basic file backend. The storage is consulted to see if the file + exists. + + """ + + def _file_exists(self, file): + if not getattr(file, '_file', None): + # No file on object. Have to check storage. + return not file.storage.exists(file.name) + return False + + def create(self, file): + """ + Generates a new image by running the processors on the source file. + + """ + file.generate() diff --git a/imagekit/imagecache/strategies.py b/imagekit/generators/strategies.py similarity index 68% rename from imagekit/imagecache/strategies.py rename to imagekit/generators/strategies.py index 28068f06..7def2a64 100644 --- a/imagekit/imagecache/strategies.py +++ b/imagekit/generators/strategies.py @@ -1,34 +1,33 @@ from django.utils.functional import LazyObject -from .actions import validate_now, clear_now from ..utils import get_singleton class JustInTime(object): """ - A caching strategy that validates the file right before it's needed. + A strategy that ensures the file exists right before it's needed. """ def before_access(self, file): - validate_now(file) + file.ensure_exists() class Optimistic(object): """ - A caching strategy that acts immediately when the cacheable file changes - and assumes that the cache files will not be removed (i.e. doesn't - revalidate on access). + A strategy that acts immediately when the source file changes and assumes + that the generated files will not be removed (i.e. it doesn't ensure the + generated file exists when it's accessed). """ def on_source_created(self, file): - validate_now(file) + file.ensure_exists() def on_source_deleted(self, file): - clear_now(file) + file.delete() def on_source_changed(self, file): - validate_now(file) + file.ensure_exists() class DictStrategy(object): @@ -40,7 +39,7 @@ def __init__(self, callbacks): class StrategyWrapper(LazyObject): def __init__(self, strategy): if isinstance(strategy, basestring): - strategy = get_singleton(strategy, 'image cache strategy') + strategy = get_singleton(strategy, 'generator strategy') elif isinstance(strategy, dict): strategy = DictStrategy(strategy) elif callable(strategy): diff --git a/imagekit/imagecache/backends.py b/imagekit/imagecache/backends.py deleted file mode 100644 index c31002f0..00000000 --- a/imagekit/imagecache/backends.py +++ /dev/null @@ -1,82 +0,0 @@ -from ..utils import get_singleton -from django.core.cache import get_cache -from django.core.exceptions import ImproperlyConfigured - - -def get_default_image_cache_backend(): - """ - Get the default image cache backend. - - """ - from django.conf import settings - return get_singleton(settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND, - 'image cache backend') - - -class InvalidImageCacheBackendError(ImproperlyConfigured): - pass - - -class CachedValidationBackend(object): - @property - def cache(self): - if not getattr(self, '_cache', None): - from django.conf import settings - self._cache = get_cache(settings.IMAGEKIT_CACHE_BACKEND) - return self._cache - - def get_key(self, file): - from django.conf import settings - return '%s%s-valid' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) - - def is_invalid(self, file): - key = self.get_key(file) - cached_value = self.cache.get(key) - if cached_value is None: - cached_value = self._is_invalid(file) - self.cache.set(key, cached_value) - return cached_value - - def validate(self, file): - if self.is_invalid(file): - self._validate(file) - self.cache.set(self.get_key(file), True) - - def invalidate(self, file): - if not self.is_invalid(file): - self._invalidate(file) - self.cache.set(self.get_key(file), False) - - -class Simple(CachedValidationBackend): - """ - The most basic image cache backend. Files are considered valid if they - exist. To invalidate a file, it's deleted; to validate one, it's generated - immediately. - - """ - - def _is_invalid(self, file): - if not getattr(file, '_file', None): - # No file on object. Have to check storage. - return not file.storage.exists(file.name) - return False - - def _validate(self, file): - """ - Generates a new image by running the processors on the source file. - - """ - file.generate() - - def invalidate(self, file): - """ - Invalidate the file by deleting it. We override ``invalidate()`` - instead of ``_invalidate()`` because we don't really care to check - whether the file is invalid or not. - - """ - file.delete(save=False) - - def clear(self, file): - file.delete(save=False) diff --git a/imagekit/management/commands/warmimagecache.py b/imagekit/management/commands/generateimages.py similarity index 68% rename from imagekit/management/commands/warmimagecache.py rename to imagekit/management/commands/generateimages.py index 9f2a8c8d..d25426ee 100644 --- a/imagekit/management/commands/warmimagecache.py +++ b/imagekit/management/commands/generateimages.py @@ -1,15 +1,16 @@ from django.core.management.base import BaseCommand import re -from ...registry import generator_registry, cacheable_registry +from ...registry import generator_registry, generatedfile_registry class Command(BaseCommand): - help = ("""Warm the image cache for the specified generators (or all generators if -none was provided). Simple, fnmatch-like wildcards are allowed, with * -matching all characters within a segment, and ** matching across segments. -(Segments are separated with colons.) So, for example, "a:*:c" will match -"a:b:c", but not "a:b:x:c", whereas "a:**:c" will match both. Subsegments -are always matched, so "a" will match "a" as well as "a:b" and "a:b:c".""") + help = ("""Generate files for the specified image generators (or all of them if +none was provided). Simple, glob-like wildcards are allowed, with * +matching all characters within a segment, and ** matching across +segments. (Segments are separated with colons.) So, for example, +"a:*:c" will match "a:b:c", but not "a:b:x:c", whereas "a:**:c" will +match both. Subsegments are always matched, so "a" will match "a" as +well as "a:b" and "a:b:c".""") args = '[generator_ids]' def handle(self, *args, **options): @@ -21,11 +22,11 @@ def handle(self, *args, **options): for generator_id in generators: self.stdout.write('Validating generator: %s\n' % generator_id) - for cacheable in cacheable_registry.get(generator_id): - self.stdout.write(' %s\n' % cacheable) + for file in generatedfile_registry.get(generator_id): + self.stdout.write(' %s\n' % file) try: # TODO: Allow other validation actions through command option - cacheable.validate() + file.ensure_exists() except Exception, err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 35c78da5..0cfcf5bd 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -26,15 +26,15 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, - source=None, cache_file_storage=None, autoconvert=None, - image_cache_backend=None, image_cache_strategy=None, spec=None, + source=None, generatedfile_storage=None, autoconvert=None, + generatedfile_backend=None, generator_strategy=None, spec=None, id=None): SpecHost.__init__(self, processors=processors, format=format, - options=options, cache_file_storage=cache_file_storage, + options=options, generatedfile_storage=generatedfile_storage, autoconvert=autoconvert, - image_cache_backend=image_cache_backend, - image_cache_strategy=image_cache_strategy, spec=spec, + generatedfile_backend=generatedfile_backend, + generator_strategy=generator_strategy, spec=spec, spec_id=id) # TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664 diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index 2324a338..e549a6b6 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...files import GeneratedImageCacheFile +from ...files import GeneratedImageFile from django.db.models.fields.files import ImageField @@ -30,7 +30,7 @@ def __get__(self, instance, owner): else: source = image_fields[0] spec = self.field.get_spec(source=source) - file = GeneratedImageCacheFile(spec) + file = GeneratedImageFile(spec) instance.__dict__[self.attname] = file return file diff --git a/imagekit/registry.py b/imagekit/registry.py index 764ba247..e746f0c6 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -52,11 +52,11 @@ def before_access_receiver(self, sender, file, **kwargs): class SourceGroupRegistry(object): """ The source group registry is responsible for listening to source_* signals - on source groups, and relaying them to the image cache strategies of the + on source groups, and relaying them to the image generator strategies of the appropriate generators. - In addition, registering a new source group also registers its cacheables - generator with the cacheable registry. + In addition, registering a new source group also registers its generated + files with that registry. """ _signals = { @@ -71,26 +71,26 @@ def __init__(self): signal.connect(self.source_group_receiver) def register(self, generator_id, source_group): - from .specs.sourcegroups import SourceGroupCacheablesGenerator + from .specs.sourcegroups import SourceGroupFilesGenerator generator_ids = self._source_groups.setdefault(source_group, set()) generator_ids.add(generator_id) - cacheable_registry.register(generator_id, - SourceGroupCacheablesGenerator(source_group, generator_id)) + generatedfile_registry.register(generator_id, + SourceGroupFilesGenerator(source_group, generator_id)) def unregister(self, generator_id, source_group): - from .specs.sourcegroups import SourceGroupCacheablesGenerator + from .specs.sourcegroups import SourceGroupFilesGenerator generator_ids = self._source_groups.setdefault(source_group, set()) if generator_id in generator_ids: generator_ids.remove(generator_id) - cacheable_registry.unregister(generator_id, - SourceGroupCacheablesGenerator(source_group, generator_id)) + generatedfile_registry.unregister(generator_id, + SourceGroupFilesGenerator(source_group, generator_id)) def source_group_receiver(self, sender, source, signal, **kwargs): """ Relay source group signals to the appropriate spec strategy. """ - from .files import GeneratedImageCacheFile + from .files import GeneratedImageFile source_group = sender # Ignore signals from unregistered groups. @@ -102,53 +102,53 @@ def source_group_receiver(self, sender, source, signal, **kwargs): callback_name = self._signals[signal] for spec in specs: - file = GeneratedImageCacheFile(spec) + file = GeneratedImageFile(spec) call_strategy_method(spec, callback_name, file=file) -class CacheableRegistry(object): +class GeneratedFileRegistry(object): """ - An object for registering cacheables with generators. The two are + An object for registering generated files with image generators. The two are associated with each other via a string id. We do this (as opposed to - associating them directly by, for example, putting a ``cacheables`` - attribute on generators) so that generators can be overridden without - losing the associated cacheables. That way, a distributable app can define - its own generators without locking the users of the app into it. + associating them directly by, for example, putting a ``generatedfiles`` + attribute on image generators) so that image generators can be overridden + without losing the associated files. That way, a distributable app can + define its own generators without locking the users of the app into it. """ def __init__(self): - self._cacheables = {} + self._generatedfiles = {} - def register(self, generator_id, cacheables): + def register(self, generator_id, generatedfiles): """ - Associates cacheables with a generator id + Associates generated files with a generator id """ - if cacheables not in self._cacheables: - self._cacheables[cacheables] = set() - self._cacheables[cacheables].add(generator_id) + if generatedfiles not in self._generatedfiles: + self._generatedfiles[generatedfiles] = set() + self._generatedfiles[generatedfiles].add(generator_id) - def unregister(self, generator_id, cacheables): + def unregister(self, generator_id, generatedfiles): """ - Disassociates cacheables with a generator id + Disassociates generated files with a generator id """ try: - self._cacheables[cacheables].remove(generator_id) + self._generatedfiles[generatedfiles].remove(generator_id) except KeyError: pass def get(self, generator_id): - for k, v in self._cacheables.items(): + for k, v in self._generatedfiles.items(): if generator_id in v: - for cacheable in k(): - yield cacheable + for file in k(): + yield file class Register(object): """ - Register generators and cacheables. + Register generators and generated files. """ def generator(self, id, generator=None): @@ -162,8 +162,8 @@ def decorator(cls): generator_registry.register(id, generator) # iterable that returns kwargs or callable that returns iterable of kwargs - def cacheables(self, generator_id, cacheables): - cacheable_registry.register(generator_id, cacheables) + def generatedfiles(self, generator_id, generatedfiles): + generatedfile_registry.register(generator_id, generatedfiles) def source_group(self, generator_id, source_group): source_group_registry.register(generator_id, source_group) @@ -171,21 +171,21 @@ def source_group(self, generator_id, source_group): class Unregister(object): """ - Unregister generators and cacheables. + Unregister generators and generated files. """ def generator(self, id, generator): generator_registry.unregister(id, generator) - def cacheables(self, generator_id, cacheables): - cacheable_registry.unregister(generator_id, cacheables) + def generatedfiles(self, generator_id, generatedfiles): + generatedfile_registry.unregister(generator_id, generatedfiles) def source_group(self, generator_id, source_group): source_group_registry.unregister(generator_id, source_group) generator_registry = GeneratorRegistry() -cacheable_registry = CacheableRegistry() +generatedfile_registry = GeneratedFileRegistry() source_group_registry = SourceGroupRegistry() register = Register() unregister = Unregister() diff --git a/imagekit/signals.py b/imagekit/signals.py index c01e30e7..36c915bd 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -1,7 +1,7 @@ from django.dispatch import Signal -# "Cacheables" (cache file) signals +# Generated file signals before_access = Signal() # Source group signals diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 7b928455..c156b52e 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -3,8 +3,8 @@ from hashlib import md5 import os import pickle -from ..imagecache.backends import get_default_image_cache_backend -from ..imagecache.strategies import StrategyWrapper +from ..generators.filebackends import get_default_generatedfile_backend +from ..generators.strategies import StrategyWrapper from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, suggest_extension from ..registry import generator_registry, register @@ -17,27 +17,27 @@ class BaseImageSpec(object): """ - cache_file_storage = None - """A Django storage system to use to save a generated cache file.""" + generatedfile_storage = None + """A Django storage system to use to save a generated file.""" - image_cache_backend = None + generatedfile_backend = None """ - An object responsible for managing the state of cached files. Defaults to an - instance of ``IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND`` + An object responsible for managing the state of generated files. Defaults to + an instance of ``IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND`` """ - image_cache_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY + generator_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_GENERATOR_STRATEGY """ A dictionary containing callbacks that allow you to customize how and when - the image cache is validated. Defaults to - ``IMAGEKIT_DEFAULT_SPEC_FIELD_IMAGE_CACHE_STRATEGY``. + the image file is created. Defaults to + ``IMAGEKIT_DEFAULT_IMAGE_GENERATOR_STRATEGY``. """ def __init__(self): - self.image_cache_backend = self.image_cache_backend or get_default_image_cache_backend() - self.image_cache_strategy = StrategyWrapper(self.image_cache_strategy) + self.generatedfile_backend = self.generatedfile_backend or get_default_generatedfile_backend() + self.generator_strategy = StrategyWrapper(self.generator_strategy) def generate(self): raise NotImplementedError @@ -83,16 +83,16 @@ def __init__(self, source): super(ImageSpec, self).__init__() @property - def cache_file_name(self): + def generatedfile_name(self): source_filename = getattr(self.source, 'name', None) if source_filename is None or os.path.isabs(source_filename): - # Generally, we put the file right in the cache directory. - dir = settings.IMAGEKIT_CACHE_DIR + # Generally, we put the file right in the generated file directory. + dir = settings.IMAGEKIT_GENERATED_FILE_DIR else: # For source files with relative names (like Django media files), # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_CACHE_DIR, + dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, os.path.splitext(source_filename)[0]) ext = suggest_extension(source_filename or '', self.format) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 3c23d642..5e821441 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -3,17 +3,17 @@ have two responsibilities: 1. To dispatch ``source_created``, ``source_changed``, and ``source_deleted`` - signals. (These will be relayed to the corresponding specs' image cache + signals. (These will be relayed to the corresponding specs' generator strategies.) 2. To provide the source files that they represent, via a generator method named - ``files()``. (This is used by the warmimagecache management command for + ``files()``. (This is used by the generateimages management command for "pre-caching" image files.) """ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..files import LazyGeneratedImageCacheFile +from ..files import LazyGeneratedImageFile from ..signals import source_created, source_changed, source_deleted @@ -135,10 +135,9 @@ def files(self): yield getattr(instance, self.image_field) -class SourceGroupCacheablesGenerator(object): +class SourceGroupFilesGenerator(object): """ - A cacheables generator for source groups. The purpose of this class is to - generate cacheables (cache files) from a source group. + A Python generator that yields generated file objects for source groups. """ def __init__(self, source_group, generator_id): @@ -157,7 +156,7 @@ def __hash__(self): def __call__(self): for source_file in self.source_group.files(): - yield LazyGeneratedImageCacheFile(self.generator_id, + yield LazyGeneratedImageFile(self.generator_id, source=source_file) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 9daacc26..555c6938 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -2,7 +2,7 @@ from django.utils.html import escape from django.utils.safestring import mark_safe from .compat import parse_bits -from ..files import GeneratedImageCacheFile +from ..files import GeneratedImageFile from ..registry import generator_registry @@ -19,12 +19,12 @@ } -def get_cache_file(context, generator_id, generator_kwargs, source=None): +def get_generatedfile(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, v in generator_kwargs.items()) generator = generator_registry.get(generator_id, **kwargs) - return GeneratedImageCacheFile(generator) + return GeneratedImageFile(generator) def parse_dimensions(dimensions): @@ -53,7 +53,7 @@ def render(self, context): autodiscover() variable_name = self.get_variable_name(context) - context[variable_name] = get_cache_file(context, self._generator_id, + context[variable_name] = get_generatedfile(context, self._generator_id, self._generator_kwargs) return '' @@ -69,7 +69,7 @@ def render(self, context): from ..utils import autodiscover autodiscover() - file = get_cache_file(context, self._generator_id, + file = get_generatedfile(context, self._generator_id, self._generator_kwargs) attrs = dict((k, v.resolve(context)) for k, v in self._html_attrs.items()) @@ -110,7 +110,7 @@ def render(self, context): kwargs.update(parse_dimensions(self._dimensions.resolve(context))) generator = generator_registry.get(generator_id, **kwargs) - context[variable_name] = GeneratedImageCacheFile(generator) + context[variable_name] = GeneratedImageFile(generator) return '' @@ -136,7 +136,7 @@ def render(self, context): kwargs.update(dimensions) generator = generator_registry.get(generator_id, **kwargs) - file = GeneratedImageCacheFile(generator) + file = GeneratedImageFile(generator) attrs = dict((k, v.resolve(context)) for k, v in self._html_attrs.items()) diff --git a/imagekit/utils.py b/imagekit/utils.py index adeb3779..59ef235b 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -425,7 +425,7 @@ def generate(generator): def call_strategy_method(generator, method_name, *args, **kwargs): - strategy = getattr(generator, 'image_cache_strategy', None) + strategy = getattr(generator, 'generator_strategy', None) fn = getattr(strategy, method_name, None) if fn is not None: fn(*args, **kwargs) From 01fad6e4c6faa2cd8ad443d39b0b1da8f503d532 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 04:07:57 -0500 Subject: [PATCH 182/527] Fix registration bug --- imagekit/registry.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index e746f0c6..3a998f06 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -44,7 +44,9 @@ def get_ids(self): def before_access_receiver(self, sender, file, **kwargs): generator = file.generator - if generator in self._generators.values(): + + # FIXME: I guess this means you can't register functions? + if generator.__class__ in self._generators.values(): # Only invoke the strategy method for registered generators. call_strategy_method(generator, 'before_access', file=file) From 8e6abc1e6578d467ad0391ef89570c3801ac8252 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 04:20:21 -0500 Subject: [PATCH 183/527] Remove ensure_exists `generate()` now plays double duty --- imagekit/files.py | 9 ++++++--- imagekit/generators/actions.py | 10 +++++----- imagekit/generators/filebackends.py | 2 +- imagekit/generators/strategies.py | 6 +++--- imagekit/management/commands/generateimages.py | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/imagekit/files.py b/imagekit/files.py index 9b07659d..441d2cb0 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -105,10 +105,13 @@ def _require_file(self): before_access.send(sender=self, file=self) return super(GeneratedImageFile, self)._require_file() - def ensure_exists(self): - return self.generatedfile_backend.ensure_exists(self) + def generate(self, force=False): + if force: + self._generate() + else: + self.generatedfile_backend.ensure_exists(self) - def generate(self): + def _generate(self): # Generate the file content = generate(self.generator) diff --git a/imagekit/generators/actions.py b/imagekit/generators/actions.py index dc565761..634bcbe1 100644 --- a/imagekit/generators/actions.py +++ b/imagekit/generators/actions.py @@ -1,5 +1,5 @@ -def ensure_exists(file): - file.ensure_exists() +def generate(file): + file.generate() try: @@ -7,15 +7,15 @@ def ensure_exists(file): except ImportError: pass else: - ensure_exists_task = task(ensure_exists) + generate_task = task(generate) -def ensure_exists_deferred(file): +def generate_deferred(file): try: import celery # NOQA except: raise ImportError("Deferred validation requires the the 'celery' library") - ensure_exists_task.delay(file) + generate_task.delay(file) def clear_now(file): diff --git a/imagekit/generators/filebackends.py b/imagekit/generators/filebackends.py index b80aa8ef..ed375c1e 100644 --- a/imagekit/generators/filebackends.py +++ b/imagekit/generators/filebackends.py @@ -61,4 +61,4 @@ def create(self, file): Generates a new image by running the processors on the source file. """ - file.generate() + file.generate(force=True) diff --git a/imagekit/generators/strategies.py b/imagekit/generators/strategies.py index 7def2a64..b1c6f564 100644 --- a/imagekit/generators/strategies.py +++ b/imagekit/generators/strategies.py @@ -9,7 +9,7 @@ class JustInTime(object): """ def before_access(self, file): - file.ensure_exists() + file.generate() class Optimistic(object): @@ -21,13 +21,13 @@ class Optimistic(object): """ def on_source_created(self, file): - file.ensure_exists() + file.generate() def on_source_deleted(self, file): file.delete() def on_source_changed(self, file): - file.ensure_exists() + file.generate() class DictStrategy(object): diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index d25426ee..569761f9 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -26,7 +26,7 @@ def handle(self, *args, **options): self.stdout.write(' %s\n' % file) try: # TODO: Allow other validation actions through command option - file.ensure_exists() + file.generate() except Exception, err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) From d6b73b8da7f0bcab1f5aa179583c73d833d41302 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 10:03:42 -0500 Subject: [PATCH 184/527] Renaming/repackaging of generated file related classes --- imagekit/conf.py | 4 +- imagekit/files.py | 78 +------------------ imagekit/generatedfiles/__init__.py | 75 ++++++++++++++++++ .../{generators => generatedfiles}/actions.py | 0 .../backends.py} | 0 .../strategies.py | 2 +- imagekit/generators/__init__.py | 0 imagekit/models/fields/__init__.py | 4 +- imagekit/models/fields/utils.py | 2 +- imagekit/registry.py | 6 +- imagekit/specs/__init__.py | 10 +-- imagekit/specs/sourcegroups.py | 4 +- imagekit/templatetags/imagekit.py | 2 +- imagekit/utils.py | 2 +- 14 files changed, 95 insertions(+), 94 deletions(-) create mode 100644 imagekit/generatedfiles/__init__.py rename imagekit/{generators => generatedfiles}/actions.py (100%) rename imagekit/{generators/filebackends.py => generatedfiles/backends.py} (100%) rename imagekit/{generators => generatedfiles}/strategies.py (95%) delete mode 100644 imagekit/generators/__init__.py diff --git a/imagekit/conf.py b/imagekit/conf.py index 7eb3afc1..4c39edc0 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,11 +3,11 @@ class ImageKitConf(AppConf): - DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generators.filebackends.Simple' + DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generatedfiles.backends.Simple' CACHE_BACKEND = None GENERATED_FILE_DIR = 'generated/images' CACHE_PREFIX = 'imagekit:' - DEFAULT_IMAGE_GENERATOR_STRATEGY = 'imagekit.generators.strategies.JustInTime' + DEFAULT_GENERATEDFILE_STRATEGY = 'imagekit.generatedfiles.strategies.JustInTime' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' def configure_cache_backend(self, value): diff --git a/imagekit/files.py b/imagekit/files.py index 441d2cb0..fb4375c2 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,13 +1,7 @@ -from django.conf import settings -from django.core.files.base import ContentFile, File -from django.core.files.images import ImageFile +from django.core.files.base import File, ContentFile from django.utils.encoding import smart_str, smart_unicode -from django.utils.functional import LazyObject import os -from .registry import generator_registry -from .signals import before_access -from .utils import (format_to_mimetype, extension_to_mimetype, get_logger, - get_singleton, generate) +from .utils import format_to_mimetype, extension_to_mimetype class BaseIKFile(File): @@ -72,63 +66,6 @@ def close(self): file.close() -class GeneratedImageFile(BaseIKFile, ImageFile): - """ - A file that represents the result of a generator. Creating an instance of - this class is not enough to trigger the generation of the file. In fact, - one of the main points of this class is to allow the creation of the file - to be deferred until the time that the image generator strategy requires it. - - """ - def __init__(self, generator, name=None, storage=None, generatedfile_backend=None): - """ - :param generator: The object responsible for generating a new image. - :param name: The filename - :param storage: A Django storage object that will be used to save the - file. - :param generatedfile_backend: The object responsible for managing the - state of the file. - - """ - self.generator = generator - - self.name = name or getattr(generator, 'generatedfile_name', None) - storage = storage or getattr(generator, 'generatedfile_storage', - None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, - 'file storage backend') - self.generatedfile_backend = generatedfile_backend or getattr(generator, - 'generatedfile_backend', None) - - super(GeneratedImageFile, self).__init__(storage=storage) - - def _require_file(self): - before_access.send(sender=self, file=self) - return super(GeneratedImageFile, self)._require_file() - - def generate(self, force=False): - if force: - self._generate() - else: - self.generatedfile_backend.ensure_exists(self) - - def _generate(self): - # Generate the file - content = generate(self.generator) - - actual_name = self.storage.save(self.name, content) - - if actual_name != self.name: - get_logger().warning('The storage backend %s did not save the file' - ' with the requested name ("%s") and instead used' - ' "%s". This may be because a file already existed with' - ' the requested name. If so, you may have meant to call' - ' ensure_exists() instead of generate(), or there may be a' - ' race condition in the file backend %s. The saved file' - ' will not be used.' % (self.storage, - self.name, actual_name, - self.generatedfile_backend)) - - class IKContentFile(ContentFile): """ Wraps a ContentFile in a file-like object with a filename and a @@ -156,14 +93,3 @@ def __str__(self): def __unicode__(self): return smart_unicode(self.file.name or u'') - - -class LazyGeneratedImageFile(LazyObject): - def __init__(self, generator_id, *args, **kwargs): - super(LazyGeneratedImageFile, self).__init__() - - def setup(): - generator = generator_registry.get(generator_id, *args, **kwargs) - self._wrapped = GeneratedImageFile(generator) - - self.__dict__['_setup'] = setup diff --git a/imagekit/generatedfiles/__init__.py b/imagekit/generatedfiles/__init__.py new file mode 100644 index 00000000..5249451e --- /dev/null +++ b/imagekit/generatedfiles/__init__.py @@ -0,0 +1,75 @@ +from django.conf import settings +from django.core.files.images import ImageFile +from django.utils.functional import LazyObject +from ..files import BaseIKFile +from ..registry import generator_registry +from ..signals import before_access +from ..utils import get_logger, get_singleton, generate + + +class GeneratedImageFile(BaseIKFile, ImageFile): + """ + A file that represents the result of a generator. Creating an instance of + this class is not enough to trigger the generation of the file. In fact, + one of the main points of this class is to allow the creation of the file + to be deferred until the time that the generated file strategy requires it. + + """ + def __init__(self, generator, name=None, storage=None, generatedfile_backend=None): + """ + :param generator: The object responsible for generating a new image. + :param name: The filename + :param storage: A Django storage object that will be used to save the + file. + :param generatedfile_backend: The object responsible for managing the + state of the file. + + """ + self.generator = generator + + self.name = name or getattr(generator, 'generatedfile_name', None) + storage = storage or getattr(generator, 'generatedfile_storage', + None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, + 'file storage backend') + self.generatedfile_backend = generatedfile_backend or getattr(generator, + 'generatedfile_backend', None) + + super(GeneratedImageFile, self).__init__(storage=storage) + + def _require_file(self): + before_access.send(sender=self, file=self) + return super(GeneratedImageFile, self)._require_file() + + def generate(self, force=False): + if force: + self._generate() + else: + self.generatedfile_backend.ensure_exists(self) + + def _generate(self): + # Generate the file + content = generate(self.generator) + + actual_name = self.storage.save(self.name, content) + + if actual_name != self.name: + get_logger().warning('The storage backend %s did not save the file' + ' with the requested name ("%s") and instead used' + ' "%s". This may be because a file already existed with' + ' the requested name. If so, you may have meant to call' + ' ensure_exists() instead of generate(), or there may be a' + ' race condition in the file backend %s. The saved file' + ' will not be used.' % (self.storage, + self.name, actual_name, + self.generatedfile_backend)) + + +class LazyGeneratedImageFile(LazyObject): + def __init__(self, generator_id, *args, **kwargs): + super(LazyGeneratedImageFile, self).__init__() + + def setup(): + generator = generator_registry.get(generator_id, *args, **kwargs) + self._wrapped = GeneratedImageFile(generator) + + self.__dict__['_setup'] = setup diff --git a/imagekit/generators/actions.py b/imagekit/generatedfiles/actions.py similarity index 100% rename from imagekit/generators/actions.py rename to imagekit/generatedfiles/actions.py diff --git a/imagekit/generators/filebackends.py b/imagekit/generatedfiles/backends.py similarity index 100% rename from imagekit/generators/filebackends.py rename to imagekit/generatedfiles/backends.py diff --git a/imagekit/generators/strategies.py b/imagekit/generatedfiles/strategies.py similarity index 95% rename from imagekit/generators/strategies.py rename to imagekit/generatedfiles/strategies.py index b1c6f564..72bc1df4 100644 --- a/imagekit/generators/strategies.py +++ b/imagekit/generatedfiles/strategies.py @@ -39,7 +39,7 @@ def __init__(self, callbacks): class StrategyWrapper(LazyObject): def __init__(self, strategy): if isinstance(strategy, basestring): - strategy = get_singleton(strategy, 'generator strategy') + strategy = get_singleton(strategy, 'generated file strategy') elif isinstance(strategy, dict): strategy = DictStrategy(strategy) elif callable(strategy): diff --git a/imagekit/generators/__init__.py b/imagekit/generators/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 0cfcf5bd..ee9a7890 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -27,14 +27,14 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, source=None, generatedfile_storage=None, autoconvert=None, - generatedfile_backend=None, generator_strategy=None, spec=None, + generatedfile_backend=None, generatedfile_strategy=None, spec=None, id=None): SpecHost.__init__(self, processors=processors, format=format, options=options, generatedfile_storage=generatedfile_storage, autoconvert=autoconvert, generatedfile_backend=generatedfile_backend, - generator_strategy=generator_strategy, spec=spec, + generatedfile_strategy=generatedfile_strategy, spec=spec, spec_id=id) # TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664 diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index e549a6b6..d9a29765 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...files import GeneratedImageFile +from ...generatedfiles import GeneratedImageFile from django.db.models.fields.files import ImageField diff --git a/imagekit/registry.py b/imagekit/registry.py index 3a998f06..309bb546 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -54,8 +54,8 @@ def before_access_receiver(self, sender, file, **kwargs): class SourceGroupRegistry(object): """ The source group registry is responsible for listening to source_* signals - on source groups, and relaying them to the image generator strategies of the - appropriate generators. + on source groups, and relaying them to the image generated file strategies + of the appropriate generators. In addition, registering a new source group also registers its generated files with that registry. @@ -92,7 +92,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): Relay source group signals to the appropriate spec strategy. """ - from .files import GeneratedImageFile + from .generatedfiles import GeneratedImageFile source_group = sender # Ignore signals from unregistered groups. diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index c156b52e..7c096a2f 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -3,8 +3,8 @@ from hashlib import md5 import os import pickle -from ..generators.filebackends import get_default_generatedfile_backend -from ..generators.strategies import StrategyWrapper +from ..generatedfiles.backends import get_default_generatedfile_backend +from ..generatedfiles.strategies import StrategyWrapper from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, suggest_extension from ..registry import generator_registry, register @@ -27,17 +27,17 @@ class BaseImageSpec(object): """ - generator_strategy = settings.IMAGEKIT_DEFAULT_IMAGE_GENERATOR_STRATEGY + generatedfile_strategy = settings.IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY """ A dictionary containing callbacks that allow you to customize how and when the image file is created. Defaults to - ``IMAGEKIT_DEFAULT_IMAGE_GENERATOR_STRATEGY``. + ``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY``. """ def __init__(self): self.generatedfile_backend = self.generatedfile_backend or get_default_generatedfile_backend() - self.generator_strategy = StrategyWrapper(self.generator_strategy) + self.generatedfile_strategy = StrategyWrapper(self.generatedfile_strategy) def generate(self): raise NotImplementedError diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 5e821441..e828f913 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -3,7 +3,7 @@ have two responsibilities: 1. To dispatch ``source_created``, ``source_changed``, and ``source_deleted`` - signals. (These will be relayed to the corresponding specs' generator + signals. (These will be relayed to the corresponding specs' generated file strategies.) 2. To provide the source files that they represent, via a generator method named ``files()``. (This is used by the generateimages management command for @@ -13,7 +13,7 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..files import LazyGeneratedImageFile +from ..generatedfiles import LazyGeneratedImageFile from ..signals import source_created, source_changed, source_deleted diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 555c6938..8a592428 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -2,7 +2,7 @@ from django.utils.html import escape from django.utils.safestring import mark_safe from .compat import parse_bits -from ..files import GeneratedImageFile +from ..generatedfiles import GeneratedImageFile from ..registry import generator_registry diff --git a/imagekit/utils.py b/imagekit/utils.py index 59ef235b..e2105765 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -425,7 +425,7 @@ def generate(generator): def call_strategy_method(generator, method_name, *args, **kwargs): - strategy = getattr(generator, 'generator_strategy', None) + strategy = getattr(generator, 'generatedfile_strategy', None) fn = getattr(strategy, method_name, None) if fn is not None: fn(*args, **kwargs) From 75962976d02592c4aa75471f6aaaed0bf0874a77 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 19:41:54 -0500 Subject: [PATCH 185/527] Add stringify methods to LazyGeneratedImageFile --- imagekit/generatedfiles/__init__.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/imagekit/generatedfiles/__init__.py b/imagekit/generatedfiles/__init__.py index 5249451e..8b1c9cd9 100644 --- a/imagekit/generatedfiles/__init__.py +++ b/imagekit/generatedfiles/__init__.py @@ -73,3 +73,18 @@ def setup(): self._wrapped = GeneratedImageFile(generator) self.__dict__['_setup'] = setup + + def __repr__(self): + if self._wrapped is None: + self._setup() + return '<%s: %s>' % (self.__class__.__name__, self or 'None') + + def __str__(self): + if self._wrapped is None: + self._setup() + return str(self._wrapped) + + def __unicode__(self): + if self._wrapped is None: + self._setup() + return unicode(self._wrapped) From bf1685dbfbbd16b6310b588f8c0bbc7712bb3698 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 22:01:01 -0500 Subject: [PATCH 186/527] Generalize get_class util --- imagekit/utils.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index e2105765..2ed14dee 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -322,23 +322,23 @@ def prepare_image(img, format): return img, save_kwargs -def get_class(path, desc): +def get_by_qname(path, desc): try: dot = path.rindex('.') except ValueError: raise ImproperlyConfigured("%s isn't a %s module." % (path, desc)) - module, classname = path[:dot], path[dot + 1:] + module, objname = path[:dot], path[dot + 1:] try: mod = import_module(module) except ImportError, e: raise ImproperlyConfigured('Error importing %s module %s: "%s"' % (desc, module, e)) try: - cls = getattr(mod, classname) - return cls + obj = getattr(mod, objname) + return obj except AttributeError: - raise ImproperlyConfigured('%s module "%s" does not define a "%s"' - ' class.' % (desc[0].upper() + desc[1:], module, classname)) + raise ImproperlyConfigured('%s module "%s" does not define "%s"' + % (desc[0].upper() + desc[1:], module, objname)) _singletons = {} @@ -346,7 +346,7 @@ def get_class(path, desc): def get_singleton(class_path, desc): global _singletons - cls = get_class(class_path, desc) + cls = get_by_qname(class_path, desc) instance = _singletons.get(cls) if not instance: instance = _singletons[cls] = cls() From e1c819e9b4b7477f5291559a44fee2ed39cb4a64 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 22:37:09 -0500 Subject: [PATCH 187/527] Allow default generatedfile name configuration w/namers --- imagekit/conf.py | 2 ++ imagekit/generatedfiles/__init__.py | 9 ++++-- imagekit/generatedfiles/namers.py | 45 +++++++++++++++++++++++++++++ imagekit/specs/__init__.py | 19 ++---------- 4 files changed, 57 insertions(+), 18 deletions(-) create mode 100644 imagekit/generatedfiles/namers.py diff --git a/imagekit/conf.py b/imagekit/conf.py index 4c39edc0..7bbb5b93 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -5,6 +5,8 @@ class ImageKitConf(AppConf): DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generatedfiles.backends.Simple' CACHE_BACKEND = None + GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.hash' + SPEC_GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.source_name_as_path' GENERATED_FILE_DIR = 'generated/images' CACHE_PREFIX = 'imagekit:' DEFAULT_GENERATEDFILE_STRATEGY = 'imagekit.generatedfiles.strategies.JustInTime' diff --git a/imagekit/generatedfiles/__init__.py b/imagekit/generatedfiles/__init__.py index 8b1c9cd9..5bc93f30 100644 --- a/imagekit/generatedfiles/__init__.py +++ b/imagekit/generatedfiles/__init__.py @@ -4,7 +4,7 @@ from ..files import BaseIKFile from ..registry import generator_registry from ..signals import before_access -from ..utils import get_logger, get_singleton, generate +from ..utils import get_logger, get_singleton, generate, get_by_qname class GeneratedImageFile(BaseIKFile, ImageFile): @@ -27,7 +27,12 @@ def __init__(self, generator, name=None, storage=None, generatedfile_backend=Non """ self.generator = generator - self.name = name or getattr(generator, 'generatedfile_name', None) + name = name or getattr(generator, 'generatedfile_name', None) + if not name: + fn = get_by_qname(settings.IMAGEKIT_GENERATEDFILE_NAMER, 'namer') + name = fn(generator) + self.name = name + storage = storage or getattr(generator, 'generatedfile_storage', None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') diff --git a/imagekit/generatedfiles/namers.py b/imagekit/generatedfiles/namers.py new file mode 100644 index 00000000..a20aa5a4 --- /dev/null +++ b/imagekit/generatedfiles/namers.py @@ -0,0 +1,45 @@ +from django.conf import settings +import os +from ..utils import format_to_extension, suggest_extension + + +def source_name_as_path(generator): + source_filename = getattr(generator.source, 'name', None) + + if source_filename is None or os.path.isabs(source_filename): + # Generally, we put the file right in the generated file directory. + dir = settings.IMAGEKIT_GENERATED_FILE_DIR + else: + # For source files with relative names (like Django media files), + # use the source's name to create the new filename. + dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + os.path.splitext(source_filename)[0]) + + ext = suggest_extension(source_filename or '', generator.format) + return os.path.normpath(os.path.join(dir, + '%s%s' % (generator.get_hash(), ext))) + + +def source_name_dot_hash(generator): + source_filename = getattr(generator.source, 'name', None) + + if source_filename is None or os.path.isabs(source_filename): + # Generally, we put the file right in the generated file directory. + dir = settings.IMAGEKIT_GENERATED_FILE_DIR + else: + # For source files with relative names (like Django media files), + # use the source's name to create the new filename. + dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + os.path.dirname(source_filename)) + + ext = suggest_extension(source_filename or '', generator.format) + basename = os.path.basename(source_filename) + return os.path.normpath(os.path.join(dir, '%s.%s%s' % ( + os.path.splitext(basename)[0], generator.get_hash()[:12], ext))) + + +def hash(generator): + format = getattr(generator, 'format', None) + ext = format_to_extension(format) if format else '' + return os.path.normpath(os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + '%s%s' % (generator.get_hash(), ext))) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 7c096a2f..cf37b6ff 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,12 +1,11 @@ from django.conf import settings from django.db.models.fields.files import ImageFieldFile from hashlib import md5 -import os import pickle from ..generatedfiles.backends import get_default_generatedfile_backend from ..generatedfiles.strategies import StrategyWrapper from ..processors import ProcessorPipeline -from ..utils import open_image, img_to_fobj, suggest_extension +from ..utils import open_image, img_to_fobj, get_by_qname from ..registry import generator_registry, register @@ -84,20 +83,8 @@ def __init__(self, source): @property def generatedfile_name(self): - source_filename = getattr(self.source, 'name', None) - - if source_filename is None or os.path.isabs(source_filename): - # Generally, we put the file right in the generated file directory. - dir = settings.IMAGEKIT_GENERATED_FILE_DIR - else: - # For source files with relative names (like Django media files), - # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, - os.path.splitext(source_filename)[0]) - - ext = suggest_extension(source_filename or '', self.format) - return os.path.normpath(os.path.join(dir, - '%s%s' % (self.get_hash(), ext))) + fn = get_by_qname(settings.IMAGEKIT_SPEC_GENERATEDFILE_NAMER, 'namer') + return fn(self) def __getstate__(self): state = self.__dict__ From 933ff79ac16578e546710369864d681df338589a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 22:38:48 -0500 Subject: [PATCH 188/527] Make settings consistent --- imagekit/conf.py | 2 +- imagekit/generatedfiles/namers.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 7bbb5b93..abeee934 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -7,7 +7,7 @@ class ImageKitConf(AppConf): CACHE_BACKEND = None GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.hash' SPEC_GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.source_name_as_path' - GENERATED_FILE_DIR = 'generated/images' + GENERATEDFILE_DIR = 'generated/images' CACHE_PREFIX = 'imagekit:' DEFAULT_GENERATEDFILE_STRATEGY = 'imagekit.generatedfiles.strategies.JustInTime' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' diff --git a/imagekit/generatedfiles/namers.py b/imagekit/generatedfiles/namers.py index a20aa5a4..062fb7ac 100644 --- a/imagekit/generatedfiles/namers.py +++ b/imagekit/generatedfiles/namers.py @@ -8,11 +8,11 @@ def source_name_as_path(generator): if source_filename is None or os.path.isabs(source_filename): # Generally, we put the file right in the generated file directory. - dir = settings.IMAGEKIT_GENERATED_FILE_DIR + dir = settings.IMAGEKIT_GENERATEDFILE_DIR else: # For source files with relative names (like Django media files), # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + dir = os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, os.path.splitext(source_filename)[0]) ext = suggest_extension(source_filename or '', generator.format) @@ -25,11 +25,11 @@ def source_name_dot_hash(generator): if source_filename is None or os.path.isabs(source_filename): # Generally, we put the file right in the generated file directory. - dir = settings.IMAGEKIT_GENERATED_FILE_DIR + dir = settings.IMAGEKIT_GENERATEDFILE_DIR else: # For source files with relative names (like Django media files), # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + dir = os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, os.path.dirname(source_filename)) ext = suggest_extension(source_filename or '', generator.format) @@ -41,5 +41,5 @@ def source_name_dot_hash(generator): def hash(generator): format = getattr(generator, 'format', None) ext = format_to_extension(format) if format else '' - return os.path.normpath(os.path.join(settings.IMAGEKIT_GENERATED_FILE_DIR, + return os.path.normpath(os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, '%s%s' % (generator.get_hash(), ext))) From 0947c1403fa1873bca27116ded1370f84adcd0af Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 31 Jan 2013 22:40:54 -0500 Subject: [PATCH 189/527] Organize settings --- imagekit/conf.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index abeee934..c81e228b 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,15 +3,17 @@ class ImageKitConf(AppConf): - DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generatedfiles.backends.Simple' - CACHE_BACKEND = None GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.hash' SPEC_GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.source_name_as_path' GENERATEDFILE_DIR = 'generated/images' - CACHE_PREFIX = 'imagekit:' + DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generatedfiles.backends.Simple' DEFAULT_GENERATEDFILE_STRATEGY = 'imagekit.generatedfiles.strategies.JustInTime' + DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' + CACHE_BACKEND = None + CACHE_PREFIX = 'imagekit:' + def configure_cache_backend(self, value): if value is None: value = 'django.core.cache.backends.dummy.DummyCache' if settings.DEBUG else 'default' From 92b11f83495bcbe7f7323d42d6ff0f5cf47aaf53 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 00:30:15 -0500 Subject: [PATCH 190/527] Use imagegenerators module, not imagespecs --- imagekit/utils.py | 12 ++++++------ tests/{imagespecs.py => imagegenerators.py} | 0 tests/test_fields.py | 2 +- tests/test_generateimage_tag.py | 2 +- tests/test_thumbnail_tag.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) rename tests/{imagespecs.py => imagegenerators.py} (100%) diff --git a/imagekit/utils.py b/imagekit/utils.py index 2ed14dee..2ac4f563 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -355,9 +355,9 @@ def get_singleton(class_path, desc): def autodiscover(): """ - Auto-discover INSTALLED_APPS imagespecs.py modules and fail silently when - not present. This forces an import on them to register any admin bits they - may want. + Auto-discover INSTALLED_APPS imagegenerators.py modules and fail silently + when not present. This forces an import on them to register any admin bits + they may want. Copied from django.contrib.admin """ @@ -370,12 +370,12 @@ def autodiscover(): mod = import_module(app) # Attempt to import the app's admin module. try: - import_module('%s.imagespecs' % app) + import_module('%s.imagegenerators' % app) except: # Decide whether to bubble up this error. If the app just - # doesn't have an imagespecs module, we can ignore the error + # doesn't have an imagegenerators module, we can ignore the error # attempting to import it, otherwise we want it to bubble up. - if module_has_submodule(mod, 'imagespecs'): + if module_has_submodule(mod, 'imagegenerators'): raise diff --git a/tests/imagespecs.py b/tests/imagegenerators.py similarity index 100% rename from tests/imagespecs.py rename to tests/imagegenerators.py diff --git a/tests/test_fields.py b/tests/test_fields.py index bce294fc..df513ee4 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -4,7 +4,7 @@ from imagekit import forms as ikforms from imagekit.processors import SmartCrop from nose.tools import eq_ -from . import imagespecs # noqa +from . import imagegenerators # noqa from .models import ProcessedImageFieldModel, ImageModel from .utils import get_image_file diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 76ad2a51..12f8d4ba 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,6 +1,6 @@ from django.template import TemplateSyntaxError from nose.tools import eq_, assert_not_in, raises, assert_not_equal -from . import imagespecs # noqa +from . import imagegenerators # noqa from .utils import render_tag, get_html_attrs diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 5fdbbb2c..235bb1b4 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -1,6 +1,6 @@ from django.template import TemplateSyntaxError from nose.tools import eq_, raises, assert_not_equal -from . import imagespecs # noqa +from . import imagegenerators # noqa from .utils import render_tag, get_html_attrs From 08ebcbcbf316a25efe72e3057c9f09243168e993 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 00:56:29 -0500 Subject: [PATCH 191/527] Change html attrs delimiter to -- --- imagekit/templatetags/imagekit.py | 8 ++++---- tests/test_generateimage_tag.py | 12 ++++++------ tests/test_thumbnail_tag.py | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 8a592428..67d24388 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -10,7 +10,7 @@ ASSIGNMENT_DELIMETER = 'as' -HTML_ATTRS_DELIMITER = 'with' +HTML_ATTRS_DELIMITER = '--' DEFAULT_THUMBNAIL_GENERATOR = 'ik:thumbnail' @@ -205,10 +205,10 @@ def generateimage(parser, token): - You can add additional attributes to the tag using "with". For example, + You can add additional attributes to the tag using "--". For example, this:: - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image with alt="Hello!" %} + {% generateimage 'myapp:thumbnail' from=mymodel.profile_image -- alt="Hello!" %} will result in the following markup:: @@ -250,7 +250,7 @@ def thumbnail(parser, token): {% generateimage 'ik:thumbnail' from=mymodel.profile_image width=100 height=100 %} - The thumbnail tag supports the "with" and "as" bits for adding html + The thumbnail tag supports the "--" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the kwargs "anchor", and "crop". diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 12f8d4ba..18b41682 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -14,25 +14,25 @@ def test_img_tag(): def test_img_tag_attrs(): - ttag = r"""{% generateimage 'testspec' from=img with alt="Hello" %}""" + ttag = r"""{% generateimage 'testspec' from=img -- alt="Hello" %}""" attrs = get_html_attrs(ttag) eq_(attrs.get('alt'), 'Hello') @raises(TemplateSyntaxError) -def test_dangling_with(): - ttag = r"""{% generateimage 'testspec' from=img with %}""" +def test_dangling_html_attrs_delimiter(): + ttag = r"""{% generateimage 'testspec' from=img -- %}""" render_tag(ttag) @raises(TemplateSyntaxError) -def test_with_assignment(): +def test_html_attrs_assignment(): """ You can either use generateimage as an assigment tag or specify html attrs, but not both. """ - ttag = r"""{% generateimage 'testspec' from=img with alt="Hello" as th %}""" + ttag = r"""{% generateimage 'testspec' from=img -- alt="Hello" as th %}""" render_tag(ttag) @@ -41,7 +41,7 @@ def test_single_dimension_attr(): If you only provide one of width or height, the other should not be added. """ - ttag = r"""{% generateimage 'testspec' from=img with width="50" %}""" + ttag = r"""{% generateimage 'testspec' from=img -- width="50" %}""" attrs = get_html_attrs(ttag) assert_not_in('height', attrs) diff --git a/tests/test_thumbnail_tag.py b/tests/test_thumbnail_tag.py index 235bb1b4..e31304af 100644 --- a/tests/test_thumbnail_tag.py +++ b/tests/test_thumbnail_tag.py @@ -14,14 +14,14 @@ def test_img_tag(): def test_img_tag_attrs(): - ttag = r"""{% thumbnail '100x100' img with alt="Hello" %}""" + ttag = r"""{% thumbnail '100x100' img -- alt="Hello" %}""" attrs = get_html_attrs(ttag) eq_(attrs.get('alt'), 'Hello') @raises(TemplateSyntaxError) -def test_dangling_with(): - ttag = r"""{% thumbnail '100x100' img with %}""" +def test_dangling_html_attrs_delimiter(): + ttag = r"""{% thumbnail '100x100' img -- %}""" render_tag(ttag) @@ -38,13 +38,13 @@ def test_too_many_args(): @raises(TemplateSyntaxError) -def test_with_assignment(): +def test_html_attrs_assignment(): """ You can either use thumbnail as an assigment tag or specify html attrs, but not both. """ - ttag = r"""{% thumbnail '100x100' img with alt="Hello" as th %}""" + ttag = r"""{% thumbnail '100x100' img -- alt="Hello" as th %}""" render_tag(ttag) From 50d83745bce1f4ee07436f4095f3435b59a59a4a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 01:02:20 -0500 Subject: [PATCH 192/527] Remove unnecessary complexity of kwarg mapping --- imagekit/templatetags/imagekit.py | 24 +++++++++--------------- tests/test_generateimage_tag.py | 12 ++++++------ 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 67d24388..956f5925 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -14,15 +14,9 @@ DEFAULT_THUMBNAIL_GENERATOR = 'ik:thumbnail' -_kwarg_map = { - 'from': 'source', -} - - def get_generatedfile(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) - kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, - v in generator_kwargs.items()) + kwargs = dict((k, v.resolve(context)) for k, v in generator_kwargs.items()) generator = generator_registry.get(generator_id, **kwargs) return GeneratedImageFile(generator) @@ -104,8 +98,8 @@ def render(self, context): variable_name = self.get_variable_name(context) generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR - kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, - v in self._generator_kwargs.items()) + kwargs = dict((k, v.resolve(context)) for k, v in + self._generator_kwargs.items()) kwargs['source'] = self._source.resolve(context) kwargs.update(parse_dimensions(self._dimensions.resolve(context))) generator = generator_registry.get(generator_id, **kwargs) @@ -130,8 +124,8 @@ def render(self, context): generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR dimensions = parse_dimensions(self._dimensions.resolve(context)) - kwargs = dict((_kwarg_map.get(k, k), v.resolve(context)) for k, - v in self._generator_kwargs.items()) + kwargs = dict((k, v.resolve(context)) for k, v in + self._generator_kwargs.items()) kwargs['source'] = self._source.resolve(context) kwargs.update(dimensions) generator = generator_registry.get(generator_id, **kwargs) @@ -199,7 +193,7 @@ def generateimage(parser, token): By default:: - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image %} + {% generateimage 'myapp:thumbnail' source=mymodel.profile_image %} generates an ```` tag:: @@ -208,7 +202,7 @@ def generateimage(parser, token): You can add additional attributes to the tag using "--". For example, this:: - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image -- alt="Hello!" %} + {% generateimage 'myapp:thumbnail' source=mymodel.profile_image -- alt="Hello!" %} will result in the following markup:: @@ -216,7 +210,7 @@ def generateimage(parser, token): For more flexibility, ``generateimage`` also works as an assignment tag:: - {% generateimage 'myapp:thumbnail' from=mymodel.profile_image as th %} + {% generateimage 'myapp:thumbnail' source=mymodel.profile_image as th %} """ @@ -248,7 +242,7 @@ def thumbnail(parser, token): is equivalent to:: - {% generateimage 'ik:thumbnail' from=mymodel.profile_image width=100 height=100 %} + {% generateimage 'ik:thumbnail' source=mymodel.profile_image width=100 height=100 %} The thumbnail tag supports the "--" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index 18b41682..e7ea0915 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -5,7 +5,7 @@ def test_img_tag(): - ttag = r"""{% generateimage 'testspec' from=img %}""" + ttag = r"""{% generateimage 'testspec' source=img %}""" attrs = get_html_attrs(ttag) expected_attrs = set(['src', 'width', 'height']) eq_(set(attrs.keys()), expected_attrs) @@ -14,14 +14,14 @@ def test_img_tag(): def test_img_tag_attrs(): - ttag = r"""{% generateimage 'testspec' from=img -- alt="Hello" %}""" + ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" %}""" attrs = get_html_attrs(ttag) eq_(attrs.get('alt'), 'Hello') @raises(TemplateSyntaxError) def test_dangling_html_attrs_delimiter(): - ttag = r"""{% generateimage 'testspec' from=img -- %}""" + ttag = r"""{% generateimage 'testspec' source=img -- %}""" render_tag(ttag) @@ -32,7 +32,7 @@ def test_html_attrs_assignment(): but not both. """ - ttag = r"""{% generateimage 'testspec' from=img -- alt="Hello" as th %}""" + ttag = r"""{% generateimage 'testspec' source=img -- alt="Hello" as th %}""" render_tag(ttag) @@ -41,12 +41,12 @@ def test_single_dimension_attr(): If you only provide one of width or height, the other should not be added. """ - ttag = r"""{% generateimage 'testspec' from=img -- width="50" %}""" + ttag = r"""{% generateimage 'testspec' source=img -- width="50" %}""" attrs = get_html_attrs(ttag) assert_not_in('height', attrs) def test_assignment_tag(): - ttag = r"""{% generateimage 'testspec' from=img as th %}{{ th.url }}""" + ttag = r"""{% generateimage 'testspec' source=img as th %}{{ th.url }}""" html = render_tag(ttag) assert_not_equal(html.strip(), '') From f94b7276b3a8464e82929c8cdcf048f77cefe9dc Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 01:21:01 -0500 Subject: [PATCH 193/527] Use "imagekit" instead of "ik" for built-in generator prefix --- imagekit/generatorlibrary.py | 2 +- imagekit/templatetags/imagekit.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index 977e960d..bc5a0f8b 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -10,4 +10,4 @@ def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): super(Thumbnail, self).__init__(**kwargs) -register.generator('ik:thumbnail', Thumbnail) +register.generator('imagekit:thumbnail', Thumbnail) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 956f5925..fbad5116 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -11,7 +11,7 @@ ASSIGNMENT_DELIMETER = 'as' HTML_ATTRS_DELIMITER = '--' -DEFAULT_THUMBNAIL_GENERATOR = 'ik:thumbnail' +DEFAULT_THUMBNAIL_GENERATOR = 'imagekit:thumbnail' def get_generatedfile(context, generator_id, generator_kwargs, source=None): @@ -242,7 +242,7 @@ def thumbnail(parser, token): is equivalent to:: - {% generateimage 'ik:thumbnail' source=mymodel.profile_image width=100 height=100 %} + {% generateimage 'imagekit:thumbnail' source=mymodel.profile_image width=100 height=100 %} The thumbnail tag supports the "--" and "as" bits for adding html attributes and assigning to a variable, respectively. It also accepts the From 58e1c7f7e0ceaebd7d2515380271dcf2c2428fa8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 01:27:54 -0500 Subject: [PATCH 194/527] Some docs --- README.rst | 261 +++++++++++++++++++++--------- imagekit/generatedfiles/namers.py | 46 ++++++ 2 files changed, 229 insertions(+), 78 deletions(-) diff --git a/README.rst b/README.rst index db024c39..3e6e97bf 100644 --- a/README.rst +++ b/README.rst @@ -36,10 +36,87 @@ Specs ----- You have one image and you want to do something to it to create another image. -That's the basic use case of ImageKit. But how do you tell ImageKit what to do? -By defining an "image spec." Specs are instructions for creating a new image -from an existing one, and there are a few ways to define one. The most basic -way is by defining an ``ImageSpec`` subclass: +But how do you tell ImageKit what to do? By defining an image spec. + +An **image spec** is a type of **image generator** that generates a new image +from a source image. + + +Defining Specs In Models +^^^^^^^^^^^^^^^^^^^^^^^^ + +The easiest way to use define an image spec is by using an ImageSpecField on +your model class: + +.. code-block:: python + + from django.db import models + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + + profile = Profile.objects.all()[0] + print profile.avatar_thumbnail.url # > /media/generated/images/982d5af84cddddfd0fbf70892b4431e4.jpg + print profile.avatar_thumbnail.width # > 100 + +As you can probably tell, ImageSpecFields work a lot like Django's +ImageFields. The difference is that they're automatically generated by +ImageKit based on the instructions you give. In the example above, the avatar +thumbnail is a resized version of the avatar image, saved as a JPEG with a +quality of 60. + +Sometimes, however, you don't need to keep the original image (the avatar in +the above example); when the user uploads an image, you just want to process it +and save the result. In those cases, you can use the ``ProcessedImageField`` +class: + +.. code-block:: python + + from django.db import models + from imagekit.models import ProcessedImageField + + class Profile(models.Model): + avatar_thumbnail = ProcessedImageField(upload_to='avatars', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + + profile = Profile.objects.all()[0] + print profile.avatar_thumbnail.url # > /media/avatars/MY-avatar.jpg + print profile.avatar_thumbnail.width # > 100 + +This is pretty similar to our previous example. We don't need to specify a +"source" any more since we're not processing another image field, but we do need +to pass an "upload_to" argument. This behaves exactly as it does for Django +``ImageField``s. + +.. note:: + + You might be wondering why we didn't need an "upload_to" argument for our + ImageSpecField. The reason is that ProcessedImageFields really are just like + ImageFields—they save the file path in the database and you need to run + syncdb (or create a migration) when you add one to your model. + + ImageSpecFields, on the other hand, are virtual—they add no fields to your + database and don't require a database. This is handy for a lot of reasons, + but it means that the path to the image file needs to be programmatically + constructed based on the source image and the spec. + + +Defining Specs Outside of Models +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Defining specs as models fields is one very convenient way to process images, +but it isn't the only way. Sometimes you can't (or don't want to) add fields to +your models, and that's okay. You can define image spec classes and use them +directly. This can be especially useful for doing image processing in views— +particularly when the processing being done depends on user input. .. code-block:: python @@ -51,125 +128,153 @@ way is by defining an ``ImageSpec`` subclass: format = 'JPEG' options = {'quality': 60} -Now that you've defined a spec, it's time to use it. The nice thing about specs -is that they can be used in many different contexts. +It's probaby not surprising that this class is capable of processing an image +in the exact same way as our ImageSpecField above. However, unlike with the +image spec model field, this class doesn't define what source the spec is acting +on, or what should be done with the result; that's up to you: -Sometimes, you may want to just use a spec to generate a new image file. This -might be useful, for example, in view code, or in scripts: +.. code-block:: python + + source_file = open('/path/to/myimage.jpg') + image_generator = Thumbnail(source=source_file) + result = image_generator.generate() + +The result of calling ``generate()`` on an image spec is a file-like object +containing our resized image, with which you can do whatever you want. For +example, if you wanted to save it to disk: .. code-block:: python - spec = Thumbnail() - new_file = spec.apply(source_file) + dest = open('/path/to/dest.jpg', 'w') + dest.write(result.read()) + dest.close() + + +Using Specs In Templates +^^^^^^^^^^^^^^^^^^^^^^^^ + +If you have a model with an ImageSpecField or ProcessedImageField, you can +easily use those processed image just as you would a normal image field: + +.. code-block:: html + + -More often, however, you'll want to register your spec with ImageKit: +(This is assuming you have a view that's setting a context variable named +"profile" to an instance of our Profile model.) + +But you can also generate processed image files directly in your template—from +any image—without adding anything to your model. In order to do this, you'll +first have to define an image generator class (remember, specs are a type of +generator) in your app somewhere, just as we did in the last section. You'll +also need a way of referring to the generator in your template, so you'll need +to register it. .. code-block:: python - from imagekit import specs - specs.register(Thumbnail, 'myapp:fancy_thumbnail') + from imagekit import ImageSpec + from imagekit.processors import ResizeToFill + + class Thumbnail(ImageSpec): + processors = [ResizeToFill(100, 50)] + format = 'JPEG' + options = {'quality': 60} + + register.generator('myapp:thumbnail', Thumbnail) + +.. note:: -Once a spec is registered with a unique name, you can start to take advantage of -ImageKit's powerful utilities to automatically generate images for you... + You can register your generator with any id you want, but choose wisely! + If you pick something too generic, you could have a conflict with another + third-party app you're using. For this reason, it's a good idea to prefix + your generator ids with the name of your app. Also, ImageKit recognizes + colons as separators when doing pattern matching (e.g. in the generateimages + management command), so it's a good idea to use those too! -.. note:: You might be wondering why we bother with the id string instead of - just passing the spec itself. The reason is that these ids allow users to - easily override specs defined in third party apps. That way, it doesn't - matter if "django-badblog" says its thumbnails are 200x200, you can just - register your own spec (using the same id the app uses) and have whatever - size thumbnails you want. +.. warning:: + This code can go in any file you want—but you need to make sure it's loaded! + In order to keep things simple, ImageKit will automatically try to load an + module named "imagegenerators" in each of your installed apps. So why don't + you just save yourself the headache and put your image specs in there? -In Templates -^^^^^^^^^^^^ +Now that we've created an image generator class and registered it with ImageKit, +we can use it in our templates! -One utility ImageKit provides for processing images is a template tag: + +generateimage +""""""""""""" + +The most generic template tag that ImageKit gives you is called "generateimage". +It requires at least one argument: the id of a registered image generator. +Additional keyword-style arguments are passed to the registered generator class. +As we saw above, image spec constructors expect a source keyword argument, so +that's what we need to pass to use our thumbnail spec: .. code-block:: html {% load imagekit %} - {% spec 'myapp:fancy_thumbnail' source_image alt='A picture of me' %} + {% generateimage 'myapp:thumbnail' source=source_image %} -Output: +This will output the following HTML: .. code-block:: html - A picture of me + -Not generating HTML image tags? No problem. The tag also functions as an -assignment tag, providing access to the underlying file object: +You can also add additional HTML attributes; just separate them from your +keyword args using two dashes: .. code-block:: html {% load imagekit %} - {% spec 'myapp:fancy_thumbnail' source_image as th %} - Click to download a cool {{ th.width }} x {{ th.height }} image! + {% generateimage 'myapp:thumbnail' source=source_image -- alt="A picture of Me" id="mypicture" %} +Not generating HTML image tags? No problem. The tag also functions as an +assignment tag, providing access to the underlying file object: -In Models -^^^^^^^^^ - -Specs can also be used to add ``ImageField``-like fields that expose the result -of applying a spec to another one of your model's fields: - -.. code-block:: python +.. code-block:: html - from django.db import models - from imagekit.models import ImageSpecField + {% load imagekit %} - class Photo(models.Model): - avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(id='myapp:fancy_thumbnail', source='avatar') + {% generateimage 'myapp:thumbnail' source=source_image as th %} + Click to download a cool {{ th.width }} x {{ th.height }} image! - photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg - print photo.avatar_thumbnail.width # > 100 -Since defining a spec, registering it, and using it in a single model field is -such a common usage, ImakeKit provides a shortcut that allow you to skip -writing a subclass of ``ImageSpec``: +thumbnail +""""""""" -.. code-block:: python +Because it's such a common use case, ImageKit also provides a "thumbnail" +template tag. - from django.db import models - from imagekit.models import ImageSpecField - from imagekit.processors import ResizeToFill +.. code-block:: html - class Photo(models.Model): - avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(processors=[ResizeToFill(100, 50)], - format='JPEG', - options={'quality': 60}, - source='avatar') + {% load imagekit %} - photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /media/CACHE/ik/982d5af84cddddfd0fbf70892b4431e4.jpg - print photo.avatar_thumbnail.width # > 100 + {% thumbnail '100x50' source_image %} -This has the exact same behavior as before, but the spec definition is inlined. -Since no ``id`` is provided, one is automatically generated based on the app -name, model, and field. +.. note:: -Specs can also be used in models to add ``ImageField``-like fields that process -a user-provided image without saving the original: + Comparing this syntax to the generateimage tag above, you'll notice a few + differences. -.. code-block:: python + First, we didn't have to specify an image generator id; unless we tell it + otherwise, thumbnail tag uses the generator registered with the id + "imagekit:thumbnail". (A custom id can be specified by passing an argument + before the dimensions.) **It's important to note that this tag is *not* + using the Thumbnail spec class we defined earlier**; it's using the + generator registered with the id "imagekit:thumbnail" which, by default, is + ``imagekit.generatorlibrary.Thumbnail``. - from django.db import models - from imagekit.models import ProcessedImageField + Second, we're passing two positional arguments (the dimensions and the + source image) as opposed to the keyword arguments we used with the + generateimage tag. Interally, however, the tag is parsing our positional + arguments and passing them as keyword arguments to our generator class. - class Photo(models.Model): - avatar_thumbnail = ProcessedImageField(spec_id='myapp:fancy_thumbnail', - upload_to='avatars') - photo = Photo.objects.all()[0] - print photo.avatar_thumbnail.url # > /media/avatars/MY-avatar_3.jpg - print photo.avatar_thumbnail.width # > 100 -Like with ``ImageSpecField``, the ``ProcessedImageField`` constructor also -has a shortcut version that allows you to inline spec definitions. In Forms diff --git a/imagekit/generatedfiles/namers.py b/imagekit/generatedfiles/namers.py index 062fb7ac..2a9f9b7e 100644 --- a/imagekit/generatedfiles/namers.py +++ b/imagekit/generatedfiles/namers.py @@ -1,9 +1,29 @@ +""" +Functions responsible for returning filenames for the given image generator. +Users are free to define their own functions; these are just some some sensible +choices. + +""" + from django.conf import settings import os from ..utils import format_to_extension, suggest_extension def source_name_as_path(generator): + """ + A namer that, given the following source file name:: + + photos/thumbnails/bulldog.jpg + + will generate a name like this:: + + /path/to/generated/images/photos/thumbnails/bulldog/5ff3233527c5ac3e4b596343b440ff67.jpg + + where "/path/to/generated/images/" is the value specified by the + ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + + """ source_filename = getattr(generator.source, 'name', None) if source_filename is None or os.path.isabs(source_filename): @@ -21,6 +41,19 @@ def source_name_as_path(generator): def source_name_dot_hash(generator): + """ + A namer that, given the following source file name:: + + photos/thumbnails/bulldog.jpg + + will generate a name like this:: + + /path/to/generated/images/photos/thumbnails/bulldog.5ff3233527c5.jpg + + where "/path/to/generated/images/" is the value specified by the + ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + + """ source_filename = getattr(generator.source, 'name', None) if source_filename is None or os.path.isabs(source_filename): @@ -39,6 +72,19 @@ def source_name_dot_hash(generator): def hash(generator): + """ + A namer that, given the following source file name:: + + photos/thumbnails/bulldog.jpg + + will generate a name like this:: + + /path/to/generated/images/5ff3233527c5ac3e4b596343b440ff67.jpg + + where "/path/to/generated/images/" is the value specified by the + ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + + """ format = getattr(generator, 'format', None) ext = format_to_extension(format) if format else '' return os.path.normpath(os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, From c9205e588ea758400aa49ac6cbecfab54ae7102a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 1 Feb 2013 23:27:36 -0500 Subject: [PATCH 195/527] More docs --- README.rst | 59 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 3e6e97bf..4c902f01 100644 --- a/README.rst +++ b/README.rst @@ -247,7 +247,7 @@ thumbnail """"""""" Because it's such a common use case, ImageKit also provides a "thumbnail" -template tag. +template tag: .. code-block:: html @@ -255,30 +255,38 @@ template tag. {% thumbnail '100x50' source_image %} -.. note:: +Like the generateimage tag, the thumbnail tag outputs an tag: + +.. code-block:: html - Comparing this syntax to the generateimage tag above, you'll notice a few - differences. + - First, we didn't have to specify an image generator id; unless we tell it - otherwise, thumbnail tag uses the generator registered with the id - "imagekit:thumbnail". (A custom id can be specified by passing an argument - before the dimensions.) **It's important to note that this tag is *not* - using the Thumbnail spec class we defined earlier**; it's using the - generator registered with the id "imagekit:thumbnail" which, by default, is - ``imagekit.generatorlibrary.Thumbnail``. +Comparing this syntax to the generateimage tag above, you'll notice a few +differences. - Second, we're passing two positional arguments (the dimensions and the - source image) as opposed to the keyword arguments we used with the - generateimage tag. Interally, however, the tag is parsing our positional - arguments and passing them as keyword arguments to our generator class. +First, we didn't have to specify an image generator id; unless we tell it +otherwise, thumbnail tag uses the generator registered with the id +"imagekit:thumbnail". **It's important to note that this tag is *not* using the +Thumbnail spec class we defined earlier**; it's using the generator registered +with the id "imagekit:thumbnail" which, by default, is +``imagekit.generatorlibrary.Thumbnail``. +Second, we're passing two positional arguments (the dimensions and the source +image) as opposed to the keyword arguments we used with the generateimage tag. +Like with the generatethumbnail tag, you can also specify additional HTML +attributes for the thumbnail tag, or use it as an assignment tag: +.. code-block:: html + + {% load imagekit %} + {% thumbnail '100x50' source_image -- alt="A picture of Me" id="mypicture" %} + {% thumbnail '100x50' source_image as th %} -In Forms -^^^^^^^^ + +Using Specs in Forms +^^^^^^^^^^^^^^^^^^^^ In addition to the model field above, there's also a form field version of the ``ProcessedImageField`` class. The functionality is basically the same (it @@ -288,18 +296,19 @@ processes an image once and saves the result), but it's used in a form class: from django import forms from imagekit.forms import ProcessedImageField + from imagekit.processors import ResizeToFill - class AvatarForm(forms.Form): - avatar_thumbnail = ProcessedImageField(spec_id='myapp:fancy_thumbnail') + class ProfileForm(forms.Form): + avatar_thumbnail = ProcessedImageField(spec_id='myapp:profile:avatar_thumbnail', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) The benefit of using ``imagekit.forms.ProcessedImageField`` (as opposed to ``imagekit.models.ProcessedImageField`` above) is that it keeps the logic for -creating the image outside of your model (in which you would use a normal -Django ``ImageField``). You can even create multiple forms, each with their own -``ProcessedImageField``, that all store their results in the same image field. - -As with the model field classes, ``imagekit.forms.ProcessedImageField`` also -has a shortcut version that allows you to inline spec definitions. +creating the image outside of your model (in which you would use a normal Django +ImageField). You can even create multiple forms, each with their own +ProcessedImageField, that all store their results in the same image field. Processors From 218f5690056c4c5b3d04d02988b1e30a02abef0b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 2 Feb 2013 19:21:32 -0500 Subject: [PATCH 196/527] Don't assign processors, so properties will work This way, a subclass can add a @property without a setter and not worry about an error. --- imagekit/specs/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index cf37b6ff..c286a442 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -49,7 +49,7 @@ class ImageSpec(BaseImageSpec): """ - processors = None + processors = [] """A list of processors to run on the original image.""" format = None @@ -78,7 +78,6 @@ class ImageSpec(BaseImageSpec): def __init__(self, source): self.source = source - self.processors = self.processors or [] super(ImageSpec, self).__init__() @property From 36c075741716dab043c1b0eb9d8fb06674b18347 Mon Sep 17 00:00:00 2001 From: Eric Eldredge Date: Sat, 2 Feb 2013 20:47:05 -0500 Subject: [PATCH 197/527] Some upgrading docs --- docs/upgrading.rst | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 docs/upgrading.rst diff --git a/docs/upgrading.rst b/docs/upgrading.rst new file mode 100644 index 00000000..a6189afb --- /dev/null +++ b/docs/upgrading.rst @@ -0,0 +1,113 @@ +Upgrading from 2.x +================== + +ImageKit 3.0 introduces new APIs and tools that augment, improve, and in some +cases entirely replace old IK workflows. Below, you'll find some useful guides +for migrating your ImageKit 2.0 apps over to the shiny new IK3. + +Model Specs +----------- + +IK3 is chock full of new features and better tools for even the most +sophisticated use cases. Despite this, not too much has changed when it +comes to the most common of use cases: processing an ``ImageField`` on a model. + +In IK2, you may have used an ``ImageSpecField`` on a model to process an +existing ``ImageField``: + +.. code-block:: python + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(image_field='avatar', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + +In IK3, things look much the same: + +.. code-block:: python + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + +The major difference is that ``ImageSpecField`` no longer takes an +``image_field`` kwarg. Instead, you define a ``source``. + + +Image Cache Backends +-------------------- + +In IK2, you could gain some control over how your cached images were generated +by providing an ``image_cache_backend``: + +.. code-block:: python + + class Photo(models.Model): + ... + thumbnail = ImageSpecField(..., image_cache_backend=MyImageCacheBackend()) + +This gave you great control over *how* your images are generated and stored, +but it could be difficult to control *when* they were generated and stored. + +IK3 retains the image cache backend concept (now called generated file backends), +but separates the 'when' control out to generated file strategies: + +.. code-block:: python + + class Photo(models.Model): + ... + thumbnail = ImageSpecField(..., + generatedfile_backend=MyGeneratedFileBackend(), + generatedfile_strategy=MyGeneratedFileStrategy()) + +If you are using the IK2 default image cache backend setting: + +.. code-block:: python + + IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND = 'path.to.MyImageCacheBackend' + +IK3 provides analogous settings for generated file backends and strategies: + +.. code-block:: python + + IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND = 'path.to.MyGeneratedFileBackend' + IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY = 'path.to.MyGeneratedFileStrategy' + +See the documentation on `generated file backends`_ and `generated file strategies`_ +for more details. + +.. _`generated file backends`: +.. _`generated file strategies`: + + +Conditional model ``processors`` +-------------------------------- + +In IK2, an ``ImageSpecField`` could take a ``processors`` callable instead of +an iterable, which allowed processing decisions to made based on other +properties of the model. IK3 does away with this feature for consistency's sake +(if one kwarg could be callable, why not all?), but provides a much more robust +solution: the custom ``spec``. See the `advanced usage`_ documentation for more. + +.. _`advanced usage`: + + +Conditonal ``cache_to`` file names +---------------------------------- + +IK2 provided a means of specifying custom generated file names for your +image specs by passing a ``cache_to`` callable to an ``ImageSpecField``. +IK3 does away with this feature, again, for consistency. + +There is a way to achieve custom file names by overriding your spec's +``generatedfile_name``, but it is not recommended, as the spec's default +behavior is to hash the combination of ``source``, ``processors``, ``format``, +and other spec options to ensure that changes to the spec always result in +unique file names. See the documentation on `specs`_ for more. + +.. _`specs`: From 1a7c0627df062e597ed915d672ec397246b56b0c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 2 Feb 2013 21:48:41 -0500 Subject: [PATCH 198/527] Starting advanced usage docs --- docs/advanced_usage/models.rst | 99 ++++++++++++++++++++++++++++++ docs/advanced_usage/optimizing.rst | 48 +++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 docs/advanced_usage/models.rst create mode 100644 docs/advanced_usage/optimizing.rst diff --git a/docs/advanced_usage/models.rst b/docs/advanced_usage/models.rst new file mode 100644 index 00000000..2ccd70d1 --- /dev/null +++ b/docs/advanced_usage/models.rst @@ -0,0 +1,99 @@ +The ``ImageSpecField`` Shorthand Syntax +--------------------------------------- + +If you've read the README, you already know what an ``ImageSpecField`` is and +the basics of defining one: + +.. code-block:: python + + from django.db import models + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + +This will create an ``avatar_thumbnail`` field which is a resized version of the +image stored in the ``avatar`` image field. But this is actually just shorthand +for creating an ``ImageSpec``, registering it, and associating it with an +``ImageSpecField``: + +.. code-block:: python + + from django.db import models + from imagekit import ImageSpec, register + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class AvatarThumbnail(ImageSpec): + processors = [ResizeToFill(100, 50)] + format = 'JPEG' + options = {'quality': 60} + + register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + spec_id='myapp:profile:avatar_thumbnail') + +Obviously, the shorthand version is a lot, well…shorter. So why would you ever +want to go through the trouble of using the long form? The answer is that the +long form—creating an image spec class and registering it—gives you a lot more +power over the generated image. + + +Specs That Change +----------------- + +As you'll remember from the README, an image spec is just a type of image +generator that generates a new image from a source image. How does the image +spec get access to the source image? Simple! It's passed to the constructor as +a keyword argument and stored as an attribute of the spec. Normally, we don't +have to concern ourselves with this; the ``ImageSpec`` knows what to do with the +source image and we're happy to let it do its thing. However, having access to +the source image in our spec class can be very useful… + +Often, when using an ``ImageSpecField``, you may want the spec to vary based on +properties of a model. (For example, you might want to store image dimensions on +the model and then use them to generate your thumbnail.) Now that we know how to +access the source image from our spec, it's a simple matter to extract its model +and use it to create our processors list. In fact, ImageKit includes a utility +for getting this information. + +.. code-block:: python + :emphasize-lines: 11-14 + + from django.db import models + from imagekit import ImageSpec, register + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + from imagekit.utils import get_field_info + + class AvatarThumbnail(ImageSpec): + format = 'JPEG' + options = {'quality': 60} + + @property + def processors(self): + model, field_name = get_field_info(self.source) + return [ResizeToFill(model.thumbnail_width, thumbnail.avatar_height)] + + register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + spec_id='myapp:profile:avatar_thumbnail') + thumbnail_width = models.PositiveIntegerField() + thumbnail_height = models.PositiveIntegerField() + +Now each avatar thumbnail will be resized according to the dimensions stored on +the model! + +Of course, processors aren't the only thing that can vary based on the model of +the source image; spec behavior can change in any way you want. diff --git a/docs/advanced_usage/optimizing.rst b/docs/advanced_usage/optimizing.rst new file mode 100644 index 00000000..ca5ef850 --- /dev/null +++ b/docs/advanced_usage/optimizing.rst @@ -0,0 +1,48 @@ +Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't +persist any data in the database. Therefore, in order to know whether an image +file needs to be generated, ImageKit needs to check if the file already exists +(using the appropriate file storage object`__). The object responsible for +performing these checks is called a *generated file backend*. + + +Cache! +------ + +By default, ImageKit checks for the existence of a generated file every time you +attempt to use the file and, if it doesn't exist, creates it synchronously. This +is a very safe behavior because it ensures that your ImageKit-generated images +are always available. However, that's a lot of checking with storage and those +kinds of operations can be slow—especially if you're using a remote storage—so +you'll want to try to avoid them as much as possible. + +Luckily, the default generated file backend makes use of Django's caching +abilities to mitigate the number of checks it actually has to do; it will use +the cache specified by the ``IMAGEKIT_CACHE_BACKEND`` to save the state of the +generated file. If your Django project is running in debug mode +(``settings.DEBUG`` is true), this will be a dummy cache by default. Otherwise, +it will use your project's default cache. + +In normal operation, your generated files will never be deleted; once they're +created, they'll stay created. So the simplest optimization you can make is to +set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, +timeout. + + +Even More Advanced +------------------ + +For many applications—particularly those using local storage for generated image +files—a cache with a long timeout is all the optimization you'll need. However, +there may be times when that simply doesn't cut it. In these cases, you'll want +to change when the generation is actually done. + +The objects responsible for specifying when generated files are created are +called *generated file strategies*. The default strategy can be set using the +``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY`` setting, and its default value is +`'imagekit.generatedfiles.strategies.JustInTime'`. As we've already seen above, +the "just in time" strategy determines whether a file needs to be generated each +time it's accessed and, if it does, generates it synchronously. + + + +__ https://docs.djangoproject.com/en/dev/ref/files/storage/ From d22c49a4652929ff1c9de55f828c3ba1dc52ba90 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 2 Feb 2013 22:01:30 -0500 Subject: [PATCH 199/527] Don't delete the file when source is deleted We can't be sure another spec isn't using this file. --- imagekit/generatedfiles/strategies.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/imagekit/generatedfiles/strategies.py b/imagekit/generatedfiles/strategies.py index 72bc1df4..7e19692f 100644 --- a/imagekit/generatedfiles/strategies.py +++ b/imagekit/generatedfiles/strategies.py @@ -23,9 +23,6 @@ class Optimistic(object): def on_source_created(self, file): file.generate() - def on_source_deleted(self, file): - file.delete() - def on_source_changed(self, file): file.generate() From 5f8f651def4f0792e416eb6e1810e4da34da206c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 2 Feb 2013 23:35:32 -0500 Subject: [PATCH 200/527] More advanced docs! --- docs/advanced_usage/optimizing.rst | 52 ++++++++++++++++++++++++++- docs/advanced_usage/source_groups.rst | 24 +++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 docs/advanced_usage/source_groups.rst diff --git a/docs/advanced_usage/optimizing.rst b/docs/advanced_usage/optimizing.rst index ca5ef850..d1f847b2 100644 --- a/docs/advanced_usage/optimizing.rst +++ b/docs/advanced_usage/optimizing.rst @@ -41,8 +41,58 @@ called *generated file strategies*. The default strategy can be set using the ``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY`` setting, and its default value is `'imagekit.generatedfiles.strategies.JustInTime'`. As we've already seen above, the "just in time" strategy determines whether a file needs to be generated each -time it's accessed and, if it does, generates it synchronously. +time it's accessed and, if it does, generates it synchronously (that is, as part +of the request-response cycle). + +Another strategy is to simply assume the file exists. This requires the fewest +number of checks (zero!), so we don't have to worry about expensive IO. The +strategy that takes this approach is +``imagekit.generatedfiles.strategies.Optimistic``. In order to use this +strategy, either set the ``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY`` setting or, +to use it on a per-generator basis, set the ``generatedfile_strategy`` attribute +of your spec or generator. Avoiding checking for file existence can be a real +boon to performance, but it also means that ImageKit has no way to know when a +file needs to be generated—well, at least not all the time. + +With image specs, we can know at least some of the times that a new file needs +to be generated: whenever the source image is created or changed. For this +reason, the optimistic strategy defines callbacks for these events. Every +`source registered with ImageKit`__ will automatically cause its specs' files to +be generated when it is created or changed. + +.. note:: + + In order to understand source registration, read :ref:`source-groups` + +If you have specs that `change based on attributes of the source`__, that's not +going to cut it, though; the file will also need to be generated when those +attributes change. Likewise, image generators that don't have sources (i.e. +generators that aren't specs) won't cause files to be generated automatically +when using the optimistic strategy. (ImageKit can't know when those need to be +generated, if not on access.) In both cases, you'll have to trigger the file +generation yourself—either by generating the file in code when necessary, or by +periodically running the ``generateimages`` management command. Luckily, +ImageKit makes this pretty easy: + +.. code-block:: python + + from imagekit.generatedfiles import LazyGeneratedImageFile + + file = LazyGeneratedImageFile('myapp:profile:avatar_thumbnail', source=source_file) + file.generate() + +One final situation in which images won't be generated automatically when using +the optimistic strategy is when you use a spec with a source that hasn't been +registered with it. Unlike the previous two examples, this situation cannot be +rectified by running the ``generateimages`` management command, for the simple +reason that the command has no way of knowing it needs to generate a file for +that spec from that source. Typically, this situation would arise when using the +template tags. Unlike ImageSpecFields, which automatically register all the +possible source images with the spec you define, the template tags +("generateimage" and "thumbnail") let you use any spec with any source. __ https://docs.djangoproject.com/en/dev/ref/files/storage/ +__ +__ diff --git a/docs/advanced_usage/source_groups.rst b/docs/advanced_usage/source_groups.rst new file mode 100644 index 00000000..36fff336 --- /dev/null +++ b/docs/advanced_usage/source_groups.rst @@ -0,0 +1,24 @@ +.. _source-groups: + +ImageKit allows you to register objects—called *source groups*—which do two +things: 1) dispatch signals when a source is created, changed, or deleted, and +2) expose a generator method that enumerates source files. When these objects +are registered (using ``imagekit.register.source_group()``), their signals will +trigger callbacks on the generated file strategies associated with image specs +that use the source. In addition, the generator method is used (indirectly) to +create the list of files to generate with the ``generateimages`` management +command. + +Currently, there is only one source group class bundled with ImageKit, +``imagekit.specs.sourcegroups.ImageFieldSourceGroup``, which represents an +ImageField on every instance of a particular model. In terms of the above +description, ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal +every time the image in Profile's avatar ImageField changes, and 2) exposes a +generator method that iterates over every Profile's "avatar" image. + +ImageKit automatically creates and registers an instance of +ImageFieldSourceGroup every time you create an ImageSpecField; that's how the +field is connected (internally) to the spec you're defining, and therefore to +the generated file strategy responsible for generating the file. It's also how +the ``generateimages`` management command is able to know which sources to +generate files for. From 59971b6cd44e5f9924f7714649d075d6d43fdb68 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 3 Feb 2013 00:11:22 -0500 Subject: [PATCH 201/527] More docs --- docs/advanced_usage/optimizing.rst | 5 +- docs/advanced_usage/source_groups.rst | 83 +++++++++++++++++++++------ 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/docs/advanced_usage/optimizing.rst b/docs/advanced_usage/optimizing.rst index d1f847b2..f567567a 100644 --- a/docs/advanced_usage/optimizing.rst +++ b/docs/advanced_usage/optimizing.rst @@ -90,7 +90,10 @@ that spec from that source. Typically, this situation would arise when using the template tags. Unlike ImageSpecFields, which automatically register all the possible source images with the spec you define, the template tags ("generateimage" and "thumbnail") let you use any spec with any source. - +Therefore, in order to generate the appropriate files using the +``generateimages`` management command, you'll need to first register a source +group that represents all of the sources you wish to use with the corresponding +specs. See :ref:`source-groups` for more information. __ https://docs.djangoproject.com/en/dev/ref/files/storage/ diff --git a/docs/advanced_usage/source_groups.rst b/docs/advanced_usage/source_groups.rst index 36fff336..c3a2d1ca 100644 --- a/docs/advanced_usage/source_groups.rst +++ b/docs/advanced_usage/source_groups.rst @@ -1,24 +1,69 @@ .. _source-groups: -ImageKit allows you to register objects—called *source groups*—which do two -things: 1) dispatch signals when a source is created, changed, or deleted, and -2) expose a generator method that enumerates source files. When these objects -are registered (using ``imagekit.register.source_group()``), their signals will -trigger callbacks on the generated file strategies associated with image specs -that use the source. In addition, the generator method is used (indirectly) to -create the list of files to generate with the ``generateimages`` management -command. - -Currently, there is only one source group class bundled with ImageKit, -``imagekit.specs.sourcegroups.ImageFieldSourceGroup``, which represents an -ImageField on every instance of a particular model. In terms of the above -description, ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal +When you run the ``generateimages`` management command, how does ImageKit know +which source images to use with which specs? Obviously, when you define an +ImageSpecField, the source image is being connected to a spec, but what's going +on underneath the hood? + +The answer is that, when you define an ImageSpecField, ImageKit automatically +creates and registers an object called a *source group*. Source groups are +responsible for two things: + +1. They dispatch signals when a source is created, changed, or deleted, and +2. They expose a generator method that enumerates source files. + +When these objects are registered (using ``imagekit.register.source_group()``), +their signals will trigger callbacks on the generated file strategies associated +with image specs that use the source. (So, for example, you can chose to +generate a file every time the source image changes.) In addition, the generator +method is used (indirectly) to create the list of files to generate with the +``generateimages`` management command. + +Currently, there is only one source group class bundled with ImageKit—the one +used by ImageSpecFields. This source group +(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField +on every instance of a particular model. In terms of the above description, the +instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal every time the image in Profile's avatar ImageField changes, and 2) exposes a generator method that iterates over every Profile's "avatar" image. -ImageKit automatically creates and registers an instance of -ImageFieldSourceGroup every time you create an ImageSpecField; that's how the -field is connected (internally) to the spec you're defining, and therefore to -the generated file strategy responsible for generating the file. It's also how -the ``generateimages`` management command is able to know which sources to -generate files for. +Chances are, this is the only source group you will ever need to use, however, +ImageKit lets you define and register custom source groups easily. This may be +useful, for example, if you're using the template tags "generateimage" and +"thumbnail" and the optimistic generated file strategy. Again, the purpose is +to tell ImageKit which specs are used with which sources (so the +"generateimages" management command can generate those files) and when the +source image has been created or changed (so that the strategy has the +opportunity to act on it). + +A simple example of a custom source group class is as follows: + +.. code-block:: python + + import glob + import os + + class JpegsInADirectory(object): + def __init__(self, dir): + self.dir = dir + + def files(self): + os.chdir(self.dir) + for name in glob.glob('*.jpg'): + yield open(name) + +Instances of this class could then be registered with one or more spec id: + +.. code-block:: python + + from imagekit import register + + register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) + +Running the "generateimages" management command would now cause thumbnails to be +generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the +JPEGs in `/path/to/some/pics`. + +Note that, since this source group doesnt send the `source_created` or +`source_changed` signals, the corresponding generated file strategy callbacks +would not be called for them. From 301adc208707cf7f1735f09e3d33bfc2d50dd1ae Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 4 Feb 2013 19:39:25 -0500 Subject: [PATCH 202/527] Let's call em cachefiles Changed my mind about 04aa72c1f9f8f7e84a0e5a6ef15fb7f74d81ecef. It's just a better description, even if different strategies can change the behavior so it isn't really very cache-like. --- README.rst | 6 ++-- docs/advanced_usage/optimizing.rst | 24 ++++++------- docs/advanced_usage/source_groups.rst | 6 ++-- docs/upgrading.rst | 24 ++++++------- .../__init__.py | 20 +++++------ .../{generatedfiles => cachefiles}/actions.py | 0 .../backends.py | 4 +-- .../{generatedfiles => cachefiles}/namers.py | 20 +++++------ .../strategies.py | 6 ++-- imagekit/conf.py | 10 +++--- .../management/commands/generateimages.py | 4 +-- imagekit/models/fields/__init__.py | 10 +++--- imagekit/models/fields/utils.py | 2 +- imagekit/registry.py | 36 +++++++++---------- imagekit/specs/__init__.py | 26 +++++++------- imagekit/specs/sourcegroups.py | 6 ++-- imagekit/templatetags/imagekit.py | 8 ++--- imagekit/utils.py | 2 +- 18 files changed, 107 insertions(+), 107 deletions(-) rename imagekit/{generatedfiles => cachefiles}/__init__.py (80%) rename imagekit/{generatedfiles => cachefiles}/actions.py (100%) rename imagekit/{generatedfiles => cachefiles}/backends.py (93%) rename imagekit/{generatedfiles => cachefiles}/namers.py (81%) rename imagekit/{generatedfiles => cachefiles}/strategies.py (86%) diff --git a/README.rst b/README.rst index 4c902f01..d31a1c69 100644 --- a/README.rst +++ b/README.rst @@ -62,7 +62,7 @@ your model class: options={'quality': 60}) profile = Profile.objects.all()[0] - print profile.avatar_thumbnail.url # > /media/generated/images/982d5af84cddddfd0fbf70892b4431e4.jpg + print profile.avatar_thumbnail.url # > /media/CACHE/images/982d5af84cddddfd0fbf70892b4431e4.jpg print profile.avatar_thumbnail.width # > 100 As you can probably tell, ImageSpecFields work a lot like Django's @@ -221,7 +221,7 @@ This will output the following HTML: .. code-block:: html - + You can also add additional HTML attributes; just separate them from your keyword args using two dashes: @@ -259,7 +259,7 @@ Like the generateimage tag, the thumbnail tag outputs an tag: .. code-block:: html - + Comparing this syntax to the generateimage tag above, you'll notice a few differences. diff --git a/docs/advanced_usage/optimizing.rst b/docs/advanced_usage/optimizing.rst index f567567a..b28c5839 100644 --- a/docs/advanced_usage/optimizing.rst +++ b/docs/advanced_usage/optimizing.rst @@ -2,27 +2,27 @@ Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't persist any data in the database. Therefore, in order to know whether an image file needs to be generated, ImageKit needs to check if the file already exists (using the appropriate file storage object`__). The object responsible for -performing these checks is called a *generated file backend*. +performing these checks is called a *cache file backend*. Cache! ------ -By default, ImageKit checks for the existence of a generated file every time you +By default, ImageKit checks for the existence of a cache file every time you attempt to use the file and, if it doesn't exist, creates it synchronously. This is a very safe behavior because it ensures that your ImageKit-generated images are always available. However, that's a lot of checking with storage and those kinds of operations can be slow—especially if you're using a remote storage—so you'll want to try to avoid them as much as possible. -Luckily, the default generated file backend makes use of Django's caching +Luckily, the default cache file backend makes use of Django's caching abilities to mitigate the number of checks it actually has to do; it will use the cache specified by the ``IMAGEKIT_CACHE_BACKEND`` to save the state of the generated file. If your Django project is running in debug mode (``settings.DEBUG`` is true), this will be a dummy cache by default. Otherwise, it will use your project's default cache. -In normal operation, your generated files will never be deleted; once they're +In normal operation, your cache files will never be deleted; once they're created, they'll stay created. So the simplest optimization you can make is to set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, timeout. @@ -36,10 +36,10 @@ files—a cache with a long timeout is all the optimization you'll need. However there may be times when that simply doesn't cut it. In these cases, you'll want to change when the generation is actually done. -The objects responsible for specifying when generated files are created are -called *generated file strategies*. The default strategy can be set using the -``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY`` setting, and its default value is -`'imagekit.generatedfiles.strategies.JustInTime'`. As we've already seen above, +The objects responsible for specifying when cache files are created are +called *cache file strategies*. The default strategy can be set using the +``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting, and its default value is +`'imagekit.cachefiles.strategies.JustInTime'`. As we've already seen above, the "just in time" strategy determines whether a file needs to be generated each time it's accessed and, if it does, generates it synchronously (that is, as part of the request-response cycle). @@ -47,9 +47,9 @@ of the request-response cycle). Another strategy is to simply assume the file exists. This requires the fewest number of checks (zero!), so we don't have to worry about expensive IO. The strategy that takes this approach is -``imagekit.generatedfiles.strategies.Optimistic``. In order to use this -strategy, either set the ``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY`` setting or, -to use it on a per-generator basis, set the ``generatedfile_strategy`` attribute +``imagekit.cachefiles.strategies.Optimistic``. In order to use this +strategy, either set the ``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting or, +to use it on a per-generator basis, set the ``cachefile_strategy`` attribute of your spec or generator. Avoiding checking for file existence can be a real boon to performance, but it also means that ImageKit has no way to know when a file needs to be generated—well, at least not all the time. @@ -76,7 +76,7 @@ ImageKit makes this pretty easy: .. code-block:: python - from imagekit.generatedfiles import LazyGeneratedImageFile + from imagekit.cachefiles import LazyGeneratedImageFile file = LazyGeneratedImageFile('myapp:profile:avatar_thumbnail', source=source_file) file.generate() diff --git a/docs/advanced_usage/source_groups.rst b/docs/advanced_usage/source_groups.rst index c3a2d1ca..d3ba0e59 100644 --- a/docs/advanced_usage/source_groups.rst +++ b/docs/advanced_usage/source_groups.rst @@ -13,7 +13,7 @@ responsible for two things: 2. They expose a generator method that enumerates source files. When these objects are registered (using ``imagekit.register.source_group()``), -their signals will trigger callbacks on the generated file strategies associated +their signals will trigger callbacks on the cache file strategies associated with image specs that use the source. (So, for example, you can chose to generate a file every time the source image changes.) In addition, the generator method is used (indirectly) to create the list of files to generate with the @@ -30,7 +30,7 @@ generator method that iterates over every Profile's "avatar" image. Chances are, this is the only source group you will ever need to use, however, ImageKit lets you define and register custom source groups easily. This may be useful, for example, if you're using the template tags "generateimage" and -"thumbnail" and the optimistic generated file strategy. Again, the purpose is +"thumbnail" and the optimistic cache file strategy. Again, the purpose is to tell ImageKit which specs are used with which sources (so the "generateimages" management command can generate those files) and when the source image has been created or changed (so that the strategy has the @@ -65,5 +65,5 @@ generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the JPEGs in `/path/to/some/pics`. Note that, since this source group doesnt send the `source_created` or -`source_changed` signals, the corresponding generated file strategy callbacks +`source_changed` signals, the corresponding cache file strategy callbacks would not be called for them. diff --git a/docs/upgrading.rst b/docs/upgrading.rst index a6189afb..7a9b4386 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -54,16 +54,16 @@ by providing an ``image_cache_backend``: This gave you great control over *how* your images are generated and stored, but it could be difficult to control *when* they were generated and stored. -IK3 retains the image cache backend concept (now called generated file backends), -but separates the 'when' control out to generated file strategies: +IK3 retains the image cache backend concept (now called cache file backends), +but separates the 'when' control out to cache file strategies: .. code-block:: python class Photo(models.Model): ... thumbnail = ImageSpecField(..., - generatedfile_backend=MyGeneratedFileBackend(), - generatedfile_strategy=MyGeneratedFileStrategy()) + cachefile_backend=MyCacheFileBackend(), + cachefile_strategy=MyCacheFileStrategy()) If you are using the IK2 default image cache backend setting: @@ -71,18 +71,18 @@ If you are using the IK2 default image cache backend setting: IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND = 'path.to.MyImageCacheBackend' -IK3 provides analogous settings for generated file backends and strategies: +IK3 provides analogous settings for cache file backends and strategies: .. code-block:: python - IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND = 'path.to.MyGeneratedFileBackend' - IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY = 'path.to.MyGeneratedFileStrategy' + IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'path.to.MyCacheFileBackend' + IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = 'path.to.MyCacheFileStrategy' -See the documentation on `generated file backends`_ and `generated file strategies`_ +See the documentation on `cache file backends`_ and `cache file strategies`_ for more details. -.. _`generated file backends`: -.. _`generated file strategies`: +.. _`cache file backends`: +.. _`cache file strategies`: Conditional model ``processors`` @@ -100,12 +100,12 @@ solution: the custom ``spec``. See the `advanced usage`_ documentation for more. Conditonal ``cache_to`` file names ---------------------------------- -IK2 provided a means of specifying custom generated file names for your +IK2 provided a means of specifying custom cache file names for your image specs by passing a ``cache_to`` callable to an ``ImageSpecField``. IK3 does away with this feature, again, for consistency. There is a way to achieve custom file names by overriding your spec's -``generatedfile_name``, but it is not recommended, as the spec's default +``cachefile_name``, but it is not recommended, as the spec's default behavior is to hash the combination of ``source``, ``processors``, ``format``, and other spec options to ensure that changes to the spec always result in unique file names. See the documentation on `specs`_ for more. diff --git a/imagekit/generatedfiles/__init__.py b/imagekit/cachefiles/__init__.py similarity index 80% rename from imagekit/generatedfiles/__init__.py rename to imagekit/cachefiles/__init__.py index 5bc93f30..25c822f4 100644 --- a/imagekit/generatedfiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -12,32 +12,32 @@ class GeneratedImageFile(BaseIKFile, ImageFile): A file that represents the result of a generator. Creating an instance of this class is not enough to trigger the generation of the file. In fact, one of the main points of this class is to allow the creation of the file - to be deferred until the time that the generated file strategy requires it. + to be deferred until the time that the cache file strategy requires it. """ - def __init__(self, generator, name=None, storage=None, generatedfile_backend=None): + def __init__(self, generator, name=None, storage=None, cachefile_backend=None): """ :param generator: The object responsible for generating a new image. :param name: The filename :param storage: A Django storage object that will be used to save the file. - :param generatedfile_backend: The object responsible for managing the + :param cachefile_backend: The object responsible for managing the state of the file. """ self.generator = generator - name = name or getattr(generator, 'generatedfile_name', None) + name = name or getattr(generator, 'cachefile_name', None) if not name: - fn = get_by_qname(settings.IMAGEKIT_GENERATEDFILE_NAMER, 'namer') + fn = get_by_qname(settings.IMAGEKIT_CACHEFILE_NAMER, 'namer') name = fn(generator) self.name = name - storage = storage or getattr(generator, 'generatedfile_storage', + storage = storage or getattr(generator, 'cachefile_storage', None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') - self.generatedfile_backend = generatedfile_backend or getattr(generator, - 'generatedfile_backend', None) + self.cachefile_backend = cachefile_backend or getattr(generator, + 'cachefile_backend', None) super(GeneratedImageFile, self).__init__(storage=storage) @@ -49,7 +49,7 @@ def generate(self, force=False): if force: self._generate() else: - self.generatedfile_backend.ensure_exists(self) + self.cachefile_backend.ensure_exists(self) def _generate(self): # Generate the file @@ -66,7 +66,7 @@ def _generate(self): ' race condition in the file backend %s. The saved file' ' will not be used.' % (self.storage, self.name, actual_name, - self.generatedfile_backend)) + self.cachefile_backend)) class LazyGeneratedImageFile(LazyObject): diff --git a/imagekit/generatedfiles/actions.py b/imagekit/cachefiles/actions.py similarity index 100% rename from imagekit/generatedfiles/actions.py rename to imagekit/cachefiles/actions.py diff --git a/imagekit/generatedfiles/backends.py b/imagekit/cachefiles/backends.py similarity index 93% rename from imagekit/generatedfiles/backends.py rename to imagekit/cachefiles/backends.py index ed375c1e..15813be4 100644 --- a/imagekit/generatedfiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -3,13 +3,13 @@ from django.core.exceptions import ImproperlyConfigured -def get_default_generatedfile_backend(): +def get_default_cachefile_backend(): """ Get the default file backend. """ from django.conf import settings - return get_singleton(settings.IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND, + return get_singleton(settings.IMAGEKIT_DEFAULT_CACHEFILE_BACKEND, 'file backend') diff --git a/imagekit/generatedfiles/namers.py b/imagekit/cachefiles/namers.py similarity index 81% rename from imagekit/generatedfiles/namers.py rename to imagekit/cachefiles/namers.py index 2a9f9b7e..d6bc95a3 100644 --- a/imagekit/generatedfiles/namers.py +++ b/imagekit/cachefiles/namers.py @@ -21,18 +21,18 @@ def source_name_as_path(generator): /path/to/generated/images/photos/thumbnails/bulldog/5ff3233527c5ac3e4b596343b440ff67.jpg where "/path/to/generated/images/" is the value specified by the - ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + ``IMAGEKIT_CACHEFILE_DIR`` setting. """ source_filename = getattr(generator.source, 'name', None) if source_filename is None or os.path.isabs(source_filename): - # Generally, we put the file right in the generated file directory. - dir = settings.IMAGEKIT_GENERATEDFILE_DIR + # Generally, we put the file right in the cache file directory. + dir = settings.IMAGEKIT_CACHEFILE_DIR else: # For source files with relative names (like Django media files), # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, + dir = os.path.join(settings.IMAGEKIT_CACHEFILE_DIR, os.path.splitext(source_filename)[0]) ext = suggest_extension(source_filename or '', generator.format) @@ -51,18 +51,18 @@ def source_name_dot_hash(generator): /path/to/generated/images/photos/thumbnails/bulldog.5ff3233527c5.jpg where "/path/to/generated/images/" is the value specified by the - ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + ``IMAGEKIT_CACHEFILE_DIR`` setting. """ source_filename = getattr(generator.source, 'name', None) if source_filename is None or os.path.isabs(source_filename): - # Generally, we put the file right in the generated file directory. - dir = settings.IMAGEKIT_GENERATEDFILE_DIR + # Generally, we put the file right in the cache file directory. + dir = settings.IMAGEKIT_CACHEFILE_DIR else: # For source files with relative names (like Django media files), # use the source's name to create the new filename. - dir = os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, + dir = os.path.join(settings.IMAGEKIT_CACHEFILE_DIR, os.path.dirname(source_filename)) ext = suggest_extension(source_filename or '', generator.format) @@ -82,10 +82,10 @@ def hash(generator): /path/to/generated/images/5ff3233527c5ac3e4b596343b440ff67.jpg where "/path/to/generated/images/" is the value specified by the - ``IMAGEKIT_GENERATEDFILE_DIR`` setting. + ``IMAGEKIT_CACHEFILE_DIR`` setting. """ format = getattr(generator, 'format', None) ext = format_to_extension(format) if format else '' - return os.path.normpath(os.path.join(settings.IMAGEKIT_GENERATEDFILE_DIR, + return os.path.normpath(os.path.join(settings.IMAGEKIT_CACHEFILE_DIR, '%s%s' % (generator.get_hash(), ext))) diff --git a/imagekit/generatedfiles/strategies.py b/imagekit/cachefiles/strategies.py similarity index 86% rename from imagekit/generatedfiles/strategies.py rename to imagekit/cachefiles/strategies.py index 7e19692f..1104de62 100644 --- a/imagekit/generatedfiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -15,8 +15,8 @@ def before_access(self, file): class Optimistic(object): """ A strategy that acts immediately when the source file changes and assumes - that the generated files will not be removed (i.e. it doesn't ensure the - generated file exists when it's accessed). + that the cache files will not be removed (i.e. it doesn't ensure the + cache file exists when it's accessed). """ @@ -36,7 +36,7 @@ def __init__(self, callbacks): class StrategyWrapper(LazyObject): def __init__(self, strategy): if isinstance(strategy, basestring): - strategy = get_singleton(strategy, 'generated file strategy') + strategy = get_singleton(strategy, 'cache file strategy') elif isinstance(strategy, dict): strategy = DictStrategy(strategy) elif callable(strategy): diff --git a/imagekit/conf.py b/imagekit/conf.py index c81e228b..3abd6f37 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -3,11 +3,11 @@ class ImageKitConf(AppConf): - GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.hash' - SPEC_GENERATEDFILE_NAMER = 'imagekit.generatedfiles.namers.source_name_as_path' - GENERATEDFILE_DIR = 'generated/images' - DEFAULT_GENERATEDFILE_BACKEND = 'imagekit.generatedfiles.backends.Simple' - DEFAULT_GENERATEDFILE_STRATEGY = 'imagekit.generatedfiles.strategies.JustInTime' + CACHEFILE_NAMER = 'imagekit.cachefiles.namers.hash' + SPEC_CACHEFILE_NAMER = 'imagekit.cachefiles.namers.source_name_as_path' + CACHEFILE_DIR = 'CACHE/images' + DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Simple' + DEFAULT_CACHEFILE_STRATEGY = 'imagekit.cachefiles.strategies.JustInTime' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 569761f9..099fe3d0 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -1,6 +1,6 @@ from django.core.management.base import BaseCommand import re -from ...registry import generator_registry, generatedfile_registry +from ...registry import generator_registry, cachefile_registry class Command(BaseCommand): @@ -22,7 +22,7 @@ def handle(self, *args, **options): for generator_id in generators: self.stdout.write('Validating generator: %s\n' % generator_id) - for file in generatedfile_registry.get(generator_id): + for file in cachefile_registry.get(generator_id): self.stdout.write(' %s\n' % file) try: # TODO: Allow other validation actions through command option diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index ee9a7890..292f410b 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -26,15 +26,15 @@ class ImageSpecField(SpecHostField): """ def __init__(self, processors=None, format=None, options=None, - source=None, generatedfile_storage=None, autoconvert=None, - generatedfile_backend=None, generatedfile_strategy=None, spec=None, + source=None, cachefile_storage=None, autoconvert=None, + cachefile_backend=None, cachefile_strategy=None, spec=None, id=None): SpecHost.__init__(self, processors=processors, format=format, - options=options, generatedfile_storage=generatedfile_storage, + options=options, cachefile_storage=cachefile_storage, autoconvert=autoconvert, - generatedfile_backend=generatedfile_backend, - generatedfile_strategy=generatedfile_strategy, spec=spec, + cachefile_backend=cachefile_backend, + cachefile_strategy=cachefile_strategy, spec=spec, spec_id=id) # TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664 diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index d9a29765..bfb6d894 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...generatedfiles import GeneratedImageFile +from ...cachefiles import GeneratedImageFile from django.db.models.fields.files import ImageField diff --git a/imagekit/registry.py b/imagekit/registry.py index 309bb546..2523f9b7 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -76,7 +76,7 @@ def register(self, generator_id, source_group): from .specs.sourcegroups import SourceGroupFilesGenerator generator_ids = self._source_groups.setdefault(source_group, set()) generator_ids.add(generator_id) - generatedfile_registry.register(generator_id, + cachefile_registry.register(generator_id, SourceGroupFilesGenerator(source_group, generator_id)) def unregister(self, generator_id, source_group): @@ -84,7 +84,7 @@ def unregister(self, generator_id, source_group): generator_ids = self._source_groups.setdefault(source_group, set()) if generator_id in generator_ids: generator_ids.remove(generator_id) - generatedfile_registry.unregister(generator_id, + cachefile_registry.unregister(generator_id, SourceGroupFilesGenerator(source_group, generator_id)) def source_group_receiver(self, sender, source, signal, **kwargs): @@ -92,7 +92,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): Relay source group signals to the appropriate spec strategy. """ - from .generatedfiles import GeneratedImageFile + from .cachefiles import GeneratedImageFile source_group = sender # Ignore signals from unregistered groups. @@ -108,11 +108,11 @@ def source_group_receiver(self, sender, source, signal, **kwargs): call_strategy_method(spec, callback_name, file=file) -class GeneratedFileRegistry(object): +class CacheFileRegistry(object): """ An object for registering generated files with image generators. The two are associated with each other via a string id. We do this (as opposed to - associating them directly by, for example, putting a ``generatedfiles`` + associating them directly by, for example, putting a ``cachefiles`` attribute on image generators) so that image generators can be overridden without losing the associated files. That way, a distributable app can define its own generators without locking the users of the app into it. @@ -120,29 +120,29 @@ class GeneratedFileRegistry(object): """ def __init__(self): - self._generatedfiles = {} + self._cachefiles = {} - def register(self, generator_id, generatedfiles): + def register(self, generator_id, cachefiles): """ Associates generated files with a generator id """ - if generatedfiles not in self._generatedfiles: - self._generatedfiles[generatedfiles] = set() - self._generatedfiles[generatedfiles].add(generator_id) + if cachefiles not in self._cachefiles: + self._cachefiles[cachefiles] = set() + self._cachefiles[cachefiles].add(generator_id) - def unregister(self, generator_id, generatedfiles): + def unregister(self, generator_id, cachefiles): """ Disassociates generated files with a generator id """ try: - self._generatedfiles[generatedfiles].remove(generator_id) + self._cachefiles[cachefiles].remove(generator_id) except KeyError: pass def get(self, generator_id): - for k, v in self._generatedfiles.items(): + for k, v in self._cachefiles.items(): if generator_id in v: for file in k(): yield file @@ -164,8 +164,8 @@ def decorator(cls): generator_registry.register(id, generator) # iterable that returns kwargs or callable that returns iterable of kwargs - def generatedfiles(self, generator_id, generatedfiles): - generatedfile_registry.register(generator_id, generatedfiles) + def cachefiles(self, generator_id, cachefiles): + cachefile_registry.register(generator_id, cachefiles) def source_group(self, generator_id, source_group): source_group_registry.register(generator_id, source_group) @@ -179,15 +179,15 @@ class Unregister(object): def generator(self, id, generator): generator_registry.unregister(id, generator) - def generatedfiles(self, generator_id, generatedfiles): - generatedfile_registry.unregister(generator_id, generatedfiles) + def cachefiles(self, generator_id, cachefiles): + cachefile_registry.unregister(generator_id, cachefiles) def source_group(self, generator_id, source_group): source_group_registry.unregister(generator_id, source_group) generator_registry = GeneratorRegistry() -generatedfile_registry = GeneratedFileRegistry() +cachefile_registry = CacheFileRegistry() source_group_registry = SourceGroupRegistry() register = Register() unregister = Unregister() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index c286a442..969dcf37 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -2,8 +2,8 @@ from django.db.models.fields.files import ImageFieldFile from hashlib import md5 import pickle -from ..generatedfiles.backends import get_default_generatedfile_backend -from ..generatedfiles.strategies import StrategyWrapper +from ..cachefiles.backends import get_default_cachefile_backend +from ..cachefiles.strategies import StrategyWrapper from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, get_by_qname from ..registry import generator_registry, register @@ -16,27 +16,27 @@ class BaseImageSpec(object): """ - generatedfile_storage = None - """A Django storage system to use to save a generated file.""" + cachefile_storage = None + """A Django storage system to use to save a cache file.""" - generatedfile_backend = None + cachefile_backend = None """ - An object responsible for managing the state of generated files. Defaults to - an instance of ``IMAGEKIT_DEFAULT_GENERATEDFILE_BACKEND`` + An object responsible for managing the state of cache files. Defaults to + an instance of ``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` """ - generatedfile_strategy = settings.IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY + cachefile_strategy = settings.IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY """ A dictionary containing callbacks that allow you to customize how and when the image file is created. Defaults to - ``IMAGEKIT_DEFAULT_GENERATEDFILE_STRATEGY``. + ``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY``. """ def __init__(self): - self.generatedfile_backend = self.generatedfile_backend or get_default_generatedfile_backend() - self.generatedfile_strategy = StrategyWrapper(self.generatedfile_strategy) + self.cachefile_backend = self.cachefile_backend or get_default_cachefile_backend() + self.cachefile_strategy = StrategyWrapper(self.cachefile_strategy) def generate(self): raise NotImplementedError @@ -81,8 +81,8 @@ def __init__(self, source): super(ImageSpec, self).__init__() @property - def generatedfile_name(self): - fn = get_by_qname(settings.IMAGEKIT_SPEC_GENERATEDFILE_NAMER, 'namer') + def cachefile_name(self): + fn = get_by_qname(settings.IMAGEKIT_SPEC_CACHEFILE_NAMER, 'namer') return fn(self) def __getstate__(self): diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index e828f913..ec85af8a 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -3,7 +3,7 @@ have two responsibilities: 1. To dispatch ``source_created``, ``source_changed``, and ``source_deleted`` - signals. (These will be relayed to the corresponding specs' generated file + signals. (These will be relayed to the corresponding specs' cache file strategies.) 2. To provide the source files that they represent, via a generator method named ``files()``. (This is used by the generateimages management command for @@ -13,7 +13,7 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..generatedfiles import LazyGeneratedImageFile +from ..cachefiles import LazyGeneratedImageFile from ..signals import source_created, source_changed, source_deleted @@ -137,7 +137,7 @@ def files(self): class SourceGroupFilesGenerator(object): """ - A Python generator that yields generated file objects for source groups. + A Python generator that yields cache file objects for source groups. """ def __init__(self, source_group, generator_id): diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index fbad5116..c845dcca 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -2,7 +2,7 @@ from django.utils.html import escape from django.utils.safestring import mark_safe from .compat import parse_bits -from ..generatedfiles import GeneratedImageFile +from ..cachefiles import GeneratedImageFile from ..registry import generator_registry @@ -14,7 +14,7 @@ DEFAULT_THUMBNAIL_GENERATOR = 'imagekit:thumbnail' -def get_generatedfile(context, generator_id, generator_kwargs, source=None): +def get_cachefile(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) kwargs = dict((k, v.resolve(context)) for k, v in generator_kwargs.items()) generator = generator_registry.get(generator_id, **kwargs) @@ -47,7 +47,7 @@ def render(self, context): autodiscover() variable_name = self.get_variable_name(context) - context[variable_name] = get_generatedfile(context, self._generator_id, + context[variable_name] = get_cachefile(context, self._generator_id, self._generator_kwargs) return '' @@ -63,7 +63,7 @@ def render(self, context): from ..utils import autodiscover autodiscover() - file = get_generatedfile(context, self._generator_id, + file = get_cachefile(context, self._generator_id, self._generator_kwargs) attrs = dict((k, v.resolve(context)) for k, v in self._html_attrs.items()) diff --git a/imagekit/utils.py b/imagekit/utils.py index 2ac4f563..ff02a50a 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -425,7 +425,7 @@ def generate(generator): def call_strategy_method(generator, method_name, *args, **kwargs): - strategy = getattr(generator, 'generatedfile_strategy', None) + strategy = getattr(generator, 'cachefile_strategy', None) fn = getattr(strategy, method_name, None) if fn is not None: fn(*args, **kwargs) From 55a2a5fc9df61f66041b33904cf1b4f1f8cce352 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 4 Feb 2013 19:57:00 -0500 Subject: [PATCH 203/527] Typo fix --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index d31a1c69..2846bab1 100644 --- a/README.rst +++ b/README.rst @@ -221,7 +221,7 @@ This will output the following HTML: .. code-block:: html - + You can also add additional HTML attributes; just separate them from your keyword args using two dashes: @@ -259,7 +259,7 @@ Like the generateimage tag, the thumbnail tag outputs an tag: .. code-block:: html - + Comparing this syntax to the generateimage tag above, you'll notice a few differences. From 34a7ab975151c2d2b6b9fc165d258f0b13edd653 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 5 Feb 2013 19:21:26 -0500 Subject: [PATCH 204/527] Remove requirements.txt What was this doing in here? --- requirements.txt | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 23b38e9c..00000000 --- a/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -Django>=1.3.1 -django-appconf>=0.5 -PIL>=1.1.7 - -# Required for tests -nose==1.2.1 -nose-progressive==1.3 -django-nose==1.1 From 0ea497261b030cb0f2be1c939d36d851988c2f3e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 5 Feb 2013 19:24:36 -0500 Subject: [PATCH 205/527] Update credits --- AUTHORS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 24968f01..03028f2c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,7 @@ ImageKit was originally written by `Justin Driscoll`_. -The field-based API was written by the bright minds at HZDG_. +The field-based API and other post-1.0 stuff was written by the bright people at +HZDG_. Maintainers ~~~~~~~~~~~ From 1f86e33d64bee2b975344223058520c0f84f77dc Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 5 Feb 2013 21:12:39 -0500 Subject: [PATCH 206/527] Doc fixes --- AUTHORS | 4 +- README.rst | 6 +- docs/advanced_usage.rst | 284 ++++++++++++++++++++++++++ docs/advanced_usage/models.rst | 99 --------- docs/advanced_usage/optimizing.rst | 101 --------- docs/advanced_usage/source_groups.rst | 69 ------- docs/apireference.rst | 29 --- docs/configuration.rst | 89 ++------ docs/index.rst | 40 +--- docs/upgrading.rst | 1 + 10 files changed, 313 insertions(+), 409 deletions(-) create mode 100644 docs/advanced_usage.rst delete mode 100644 docs/advanced_usage/models.rst delete mode 100644 docs/advanced_usage/optimizing.rst delete mode 100644 docs/advanced_usage/source_groups.rst delete mode 100644 docs/apireference.rst diff --git a/AUTHORS b/AUTHORS index 03028f2c..d91cb936 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,7 +4,7 @@ The field-based API and other post-1.0 stuff was written by the bright people at HZDG_. Maintainers -~~~~~~~~~~~ +----------- * `Bryan Veloso`_ * `Matthew Tretter`_ @@ -12,7 +12,7 @@ Maintainers * `Greg Newman`_ Contributors -~~~~~~~~~~~~ +------------ * `Josh Ourisman`_ * `Jonathan Slenders`_ diff --git a/README.rst b/README.rst index 2846bab1..2f2ad5d1 100644 --- a/README.rst +++ b/README.rst @@ -94,7 +94,7 @@ class: This is pretty similar to our previous example. We don't need to specify a "source" any more since we're not processing another image field, but we do need to pass an "upload_to" argument. This behaves exactly as it does for Django -``ImageField``s. +ImageFields. .. note:: @@ -393,7 +393,7 @@ AdminThumbnail can even use a custom template. For more information, see Community ---------- +========= Please use `the GitHub issue tracker `_ to report bugs with django-imagekit. `A mailing list `_ @@ -402,7 +402,7 @@ also exists to discuss the project and ask questions, as well as the official Contributing ------------- +============ We love contributions! And you don't have to be an expert with the library—or even Django—to contribute either: ImageKit's processors are standalone classes diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst new file mode 100644 index 00000000..917b642c --- /dev/null +++ b/docs/advanced_usage.rst @@ -0,0 +1,284 @@ +Advanced Usage +************** + + +Models +====== + + +The ``ImageSpecField`` Shorthand Syntax +--------------------------------------- + +If you've read the README, you already know what an ``ImageSpecField`` is and +the basics of defining one: + +.. code-block:: python + + from django.db import models + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + processors=[ResizeToFill(100, 50)], + format='JPEG', + options={'quality': 60}) + +This will create an ``avatar_thumbnail`` field which is a resized version of the +image stored in the ``avatar`` image field. But this is actually just shorthand +for creating an ``ImageSpec``, registering it, and associating it with an +``ImageSpecField``: + +.. code-block:: python + + from django.db import models + from imagekit import ImageSpec, register + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + + class AvatarThumbnail(ImageSpec): + processors = [ResizeToFill(100, 50)] + format = 'JPEG' + options = {'quality': 60} + + register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + spec_id='myapp:profile:avatar_thumbnail') + +Obviously, the shorthand version is a lot, well…shorter. So why would you ever +want to go through the trouble of using the long form? The answer is that the +long form—creating an image spec class and registering it—gives you a lot more +power over the generated image. + + +.. _dynamic-specs: + +Specs That Change +----------------- + +As you'll remember from the README, an image spec is just a type of image +generator that generates a new image from a source image. How does the image +spec get access to the source image? Simple! It's passed to the constructor as +a keyword argument and stored as an attribute of the spec. Normally, we don't +have to concern ourselves with this; the ``ImageSpec`` knows what to do with the +source image and we're happy to let it do its thing. However, having access to +the source image in our spec class can be very useful… + +Often, when using an ``ImageSpecField``, you may want the spec to vary based on +properties of a model. (For example, you might want to store image dimensions on +the model and then use them to generate your thumbnail.) Now that we know how to +access the source image from our spec, it's a simple matter to extract its model +and use it to create our processors list. In fact, ImageKit includes a utility +for getting this information. + +.. code-block:: python + :emphasize-lines: 11-14 + + from django.db import models + from imagekit import ImageSpec, register + from imagekit.models import ImageSpecField + from imagekit.processors import ResizeToFill + from imagekit.utils import get_field_info + + class AvatarThumbnail(ImageSpec): + format = 'JPEG' + options = {'quality': 60} + + @property + def processors(self): + model, field_name = get_field_info(self.source) + return [ResizeToFill(model.thumbnail_width, thumbnail.avatar_height)] + + register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) + + class Profile(models.Model): + avatar = models.ImageField(upload_to='avatars') + avatar_thumbnail = ImageSpecField(source='avatar', + spec_id='myapp:profile:avatar_thumbnail') + thumbnail_width = models.PositiveIntegerField() + thumbnail_height = models.PositiveIntegerField() + +Now each avatar thumbnail will be resized according to the dimensions stored on +the model! + +Of course, processors aren't the only thing that can vary based on the model of +the source image; spec behavior can change in any way you want. + + +Optimizing +========== + +Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't +persist any data in the database. Therefore, in order to know whether an image +file needs to be generated, ImageKit needs to check if the file already exists +(using the appropriate file storage object`__). The object responsible for +performing these checks is called a *cache file backend*. + + +Cache! +------ + +By default, ImageKit checks for the existence of a cache file every time you +attempt to use the file and, if it doesn't exist, creates it synchronously. This +is a very safe behavior because it ensures that your ImageKit-generated images +are always available. However, that's a lot of checking with storage and those +kinds of operations can be slow—especially if you're using a remote storage—so +you'll want to try to avoid them as much as possible. + +Luckily, the default cache file backend makes use of Django's caching +abilities to mitigate the number of checks it actually has to do; it will use +the cache specified by the ``IMAGEKIT_CACHE_BACKEND`` to save the state of the +generated file. If your Django project is running in debug mode +(``settings.DEBUG`` is true), this will be a dummy cache by default. Otherwise, +it will use your project's default cache. + +In normal operation, your cache files will never be deleted; once they're +created, they'll stay created. So the simplest optimization you can make is to +set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, +timeout. + + +Even More Advanced +------------------ + +For many applications—particularly those using local storage for generated image +files—a cache with a long timeout is all the optimization you'll need. However, +there may be times when that simply doesn't cut it. In these cases, you'll want +to change when the generation is actually done. + +The objects responsible for specifying when cache files are created are +called *cache file strategies*. The default strategy can be set using the +``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting, and its default value is +`'imagekit.cachefiles.strategies.JustInTime'`. As we've already seen above, +the "just in time" strategy determines whether a file needs to be generated each +time it's accessed and, if it does, generates it synchronously (that is, as part +of the request-response cycle). + +Another strategy is to simply assume the file exists. This requires the fewest +number of checks (zero!), so we don't have to worry about expensive IO. The +strategy that takes this approach is +``imagekit.cachefiles.strategies.Optimistic``. In order to use this +strategy, either set the ``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting or, +to use it on a per-generator basis, set the ``cachefile_strategy`` attribute +of your spec or generator. Avoiding checking for file existence can be a real +boon to performance, but it also means that ImageKit has no way to know when a +file needs to be generated—well, at least not all the time. + +With image specs, we can know at least some of the times that a new file needs +to be generated: whenever the source image is created or changed. For this +reason, the optimistic strategy defines callbacks for these events. Every +source registered with ImageKit will automatically cause its specs' files to be +generated when it is created or changed. + +.. note:: + + In order to understand source registration, read :ref:`source-groups` + +If you have specs that :ref:`change based on attributes of the source +`, that's not going to cut it, though; the file will also need to +be generated when those attributes change. Likewise, image generators that don't +have sources (i.e. generators that aren't specs) won't cause files to be +generated automatically when using the optimistic strategy. (ImageKit can't know +when those need to be generated, if not on access.) In both cases, you'll have +to trigger the file generation yourself—either by generating the file in code +when necessary, or by periodically running the ``generateimages`` management +command. Luckily, ImageKit makes this pretty easy: + +.. code-block:: python + + from imagekit.cachefiles import LazyGeneratedImageFile + + file = LazyGeneratedImageFile('myapp:profile:avatar_thumbnail', source=source_file) + file.generate() + +One final situation in which images won't be generated automatically when using +the optimistic strategy is when you use a spec with a source that hasn't been +registered with it. Unlike the previous two examples, this situation cannot be +rectified by running the ``generateimages`` management command, for the simple +reason that the command has no way of knowing it needs to generate a file for +that spec from that source. Typically, this situation would arise when using the +template tags. Unlike ImageSpecFields, which automatically register all the +possible source images with the spec you define, the template tags +("generateimage" and "thumbnail") let you use any spec with any source. +Therefore, in order to generate the appropriate files using the +``generateimages`` management command, you'll need to first register a source +group that represents all of the sources you wish to use with the corresponding +specs. See :ref:`source-groups` for more information. + + +.. _source-groups: + +Source Groups +============= + +When you run the ``generateimages`` management command, how does ImageKit know +which source images to use with which specs? Obviously, when you define an +ImageSpecField, the source image is being connected to a spec, but what's going +on underneath the hood? + +The answer is that, when you define an ImageSpecField, ImageKit automatically +creates and registers an object called a *source group*. Source groups are +responsible for two things: + +1. They dispatch signals when a source is created, changed, or deleted, and +2. They expose a generator method that enumerates source files. + +When these objects are registered (using ``imagekit.register.source_group()``), +their signals will trigger callbacks on the cache file strategies associated +with image specs that use the source. (So, for example, you can chose to +generate a file every time the source image changes.) In addition, the generator +method is used (indirectly) to create the list of files to generate with the +``generateimages`` management command. + +Currently, there is only one source group class bundled with ImageKit—the one +used by ImageSpecFields. This source group +(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField +on every instance of a particular model. In terms of the above description, the +instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal +every time the image in Profile's avatar ImageField changes, and 2) exposes a +generator method that iterates over every Profile's "avatar" image. + +Chances are, this is the only source group you will ever need to use, however, +ImageKit lets you define and register custom source groups easily. This may be +useful, for example, if you're using the template tags "generateimage" and +"thumbnail" and the optimistic cache file strategy. Again, the purpose is +to tell ImageKit which specs are used with which sources (so the +"generateimages" management command can generate those files) and when the +source image has been created or changed (so that the strategy has the +opportunity to act on it). + +A simple example of a custom source group class is as follows: + +.. code-block:: python + + import glob + import os + + class JpegsInADirectory(object): + def __init__(self, dir): + self.dir = dir + + def files(self): + os.chdir(self.dir) + for name in glob.glob('*.jpg'): + yield open(name) + +Instances of this class could then be registered with one or more spec id: + +.. code-block:: python + + from imagekit import register + + register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) + +Running the "generateimages" management command would now cause thumbnails to be +generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the +JPEGs in `/path/to/some/pics`. + +Note that, since this source group doesnt send the `source_created` or +`source_changed` signals, the corresponding cache file strategy callbacks +would not be called for them. diff --git a/docs/advanced_usage/models.rst b/docs/advanced_usage/models.rst deleted file mode 100644 index 2ccd70d1..00000000 --- a/docs/advanced_usage/models.rst +++ /dev/null @@ -1,99 +0,0 @@ -The ``ImageSpecField`` Shorthand Syntax ---------------------------------------- - -If you've read the README, you already know what an ``ImageSpecField`` is and -the basics of defining one: - -.. code-block:: python - - from django.db import models - from imagekit.models import ImageSpecField - from imagekit.processors import ResizeToFill - - class Profile(models.Model): - avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(source='avatar', - processors=[ResizeToFill(100, 50)], - format='JPEG', - options={'quality': 60}) - -This will create an ``avatar_thumbnail`` field which is a resized version of the -image stored in the ``avatar`` image field. But this is actually just shorthand -for creating an ``ImageSpec``, registering it, and associating it with an -``ImageSpecField``: - -.. code-block:: python - - from django.db import models - from imagekit import ImageSpec, register - from imagekit.models import ImageSpecField - from imagekit.processors import ResizeToFill - - class AvatarThumbnail(ImageSpec): - processors = [ResizeToFill(100, 50)] - format = 'JPEG' - options = {'quality': 60} - - register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) - - class Profile(models.Model): - avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(source='avatar', - spec_id='myapp:profile:avatar_thumbnail') - -Obviously, the shorthand version is a lot, well…shorter. So why would you ever -want to go through the trouble of using the long form? The answer is that the -long form—creating an image spec class and registering it—gives you a lot more -power over the generated image. - - -Specs That Change ------------------ - -As you'll remember from the README, an image spec is just a type of image -generator that generates a new image from a source image. How does the image -spec get access to the source image? Simple! It's passed to the constructor as -a keyword argument and stored as an attribute of the spec. Normally, we don't -have to concern ourselves with this; the ``ImageSpec`` knows what to do with the -source image and we're happy to let it do its thing. However, having access to -the source image in our spec class can be very useful… - -Often, when using an ``ImageSpecField``, you may want the spec to vary based on -properties of a model. (For example, you might want to store image dimensions on -the model and then use them to generate your thumbnail.) Now that we know how to -access the source image from our spec, it's a simple matter to extract its model -and use it to create our processors list. In fact, ImageKit includes a utility -for getting this information. - -.. code-block:: python - :emphasize-lines: 11-14 - - from django.db import models - from imagekit import ImageSpec, register - from imagekit.models import ImageSpecField - from imagekit.processors import ResizeToFill - from imagekit.utils import get_field_info - - class AvatarThumbnail(ImageSpec): - format = 'JPEG' - options = {'quality': 60} - - @property - def processors(self): - model, field_name = get_field_info(self.source) - return [ResizeToFill(model.thumbnail_width, thumbnail.avatar_height)] - - register.generator('myapp:profile:avatar_thumbnail', AvatarThumbnail) - - class Profile(models.Model): - avatar = models.ImageField(upload_to='avatars') - avatar_thumbnail = ImageSpecField(source='avatar', - spec_id='myapp:profile:avatar_thumbnail') - thumbnail_width = models.PositiveIntegerField() - thumbnail_height = models.PositiveIntegerField() - -Now each avatar thumbnail will be resized according to the dimensions stored on -the model! - -Of course, processors aren't the only thing that can vary based on the model of -the source image; spec behavior can change in any way you want. diff --git a/docs/advanced_usage/optimizing.rst b/docs/advanced_usage/optimizing.rst deleted file mode 100644 index b28c5839..00000000 --- a/docs/advanced_usage/optimizing.rst +++ /dev/null @@ -1,101 +0,0 @@ -Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't -persist any data in the database. Therefore, in order to know whether an image -file needs to be generated, ImageKit needs to check if the file already exists -(using the appropriate file storage object`__). The object responsible for -performing these checks is called a *cache file backend*. - - -Cache! ------- - -By default, ImageKit checks for the existence of a cache file every time you -attempt to use the file and, if it doesn't exist, creates it synchronously. This -is a very safe behavior because it ensures that your ImageKit-generated images -are always available. However, that's a lot of checking with storage and those -kinds of operations can be slow—especially if you're using a remote storage—so -you'll want to try to avoid them as much as possible. - -Luckily, the default cache file backend makes use of Django's caching -abilities to mitigate the number of checks it actually has to do; it will use -the cache specified by the ``IMAGEKIT_CACHE_BACKEND`` to save the state of the -generated file. If your Django project is running in debug mode -(``settings.DEBUG`` is true), this will be a dummy cache by default. Otherwise, -it will use your project's default cache. - -In normal operation, your cache files will never be deleted; once they're -created, they'll stay created. So the simplest optimization you can make is to -set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, -timeout. - - -Even More Advanced ------------------- - -For many applications—particularly those using local storage for generated image -files—a cache with a long timeout is all the optimization you'll need. However, -there may be times when that simply doesn't cut it. In these cases, you'll want -to change when the generation is actually done. - -The objects responsible for specifying when cache files are created are -called *cache file strategies*. The default strategy can be set using the -``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting, and its default value is -`'imagekit.cachefiles.strategies.JustInTime'`. As we've already seen above, -the "just in time" strategy determines whether a file needs to be generated each -time it's accessed and, if it does, generates it synchronously (that is, as part -of the request-response cycle). - -Another strategy is to simply assume the file exists. This requires the fewest -number of checks (zero!), so we don't have to worry about expensive IO. The -strategy that takes this approach is -``imagekit.cachefiles.strategies.Optimistic``. In order to use this -strategy, either set the ``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting or, -to use it on a per-generator basis, set the ``cachefile_strategy`` attribute -of your spec or generator. Avoiding checking for file existence can be a real -boon to performance, but it also means that ImageKit has no way to know when a -file needs to be generated—well, at least not all the time. - -With image specs, we can know at least some of the times that a new file needs -to be generated: whenever the source image is created or changed. For this -reason, the optimistic strategy defines callbacks for these events. Every -`source registered with ImageKit`__ will automatically cause its specs' files to -be generated when it is created or changed. - -.. note:: - - In order to understand source registration, read :ref:`source-groups` - -If you have specs that `change based on attributes of the source`__, that's not -going to cut it, though; the file will also need to be generated when those -attributes change. Likewise, image generators that don't have sources (i.e. -generators that aren't specs) won't cause files to be generated automatically -when using the optimistic strategy. (ImageKit can't know when those need to be -generated, if not on access.) In both cases, you'll have to trigger the file -generation yourself—either by generating the file in code when necessary, or by -periodically running the ``generateimages`` management command. Luckily, -ImageKit makes this pretty easy: - -.. code-block:: python - - from imagekit.cachefiles import LazyGeneratedImageFile - - file = LazyGeneratedImageFile('myapp:profile:avatar_thumbnail', source=source_file) - file.generate() - -One final situation in which images won't be generated automatically when using -the optimistic strategy is when you use a spec with a source that hasn't been -registered with it. Unlike the previous two examples, this situation cannot be -rectified by running the ``generateimages`` management command, for the simple -reason that the command has no way of knowing it needs to generate a file for -that spec from that source. Typically, this situation would arise when using the -template tags. Unlike ImageSpecFields, which automatically register all the -possible source images with the spec you define, the template tags -("generateimage" and "thumbnail") let you use any spec with any source. -Therefore, in order to generate the appropriate files using the -``generateimages`` management command, you'll need to first register a source -group that represents all of the sources you wish to use with the corresponding -specs. See :ref:`source-groups` for more information. - - -__ https://docs.djangoproject.com/en/dev/ref/files/storage/ -__ -__ diff --git a/docs/advanced_usage/source_groups.rst b/docs/advanced_usage/source_groups.rst deleted file mode 100644 index d3ba0e59..00000000 --- a/docs/advanced_usage/source_groups.rst +++ /dev/null @@ -1,69 +0,0 @@ -.. _source-groups: - -When you run the ``generateimages`` management command, how does ImageKit know -which source images to use with which specs? Obviously, when you define an -ImageSpecField, the source image is being connected to a spec, but what's going -on underneath the hood? - -The answer is that, when you define an ImageSpecField, ImageKit automatically -creates and registers an object called a *source group*. Source groups are -responsible for two things: - -1. They dispatch signals when a source is created, changed, or deleted, and -2. They expose a generator method that enumerates source files. - -When these objects are registered (using ``imagekit.register.source_group()``), -their signals will trigger callbacks on the cache file strategies associated -with image specs that use the source. (So, for example, you can chose to -generate a file every time the source image changes.) In addition, the generator -method is used (indirectly) to create the list of files to generate with the -``generateimages`` management command. - -Currently, there is only one source group class bundled with ImageKit—the one -used by ImageSpecFields. This source group -(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField -on every instance of a particular model. In terms of the above description, the -instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal -every time the image in Profile's avatar ImageField changes, and 2) exposes a -generator method that iterates over every Profile's "avatar" image. - -Chances are, this is the only source group you will ever need to use, however, -ImageKit lets you define and register custom source groups easily. This may be -useful, for example, if you're using the template tags "generateimage" and -"thumbnail" and the optimistic cache file strategy. Again, the purpose is -to tell ImageKit which specs are used with which sources (so the -"generateimages" management command can generate those files) and when the -source image has been created or changed (so that the strategy has the -opportunity to act on it). - -A simple example of a custom source group class is as follows: - -.. code-block:: python - - import glob - import os - - class JpegsInADirectory(object): - def __init__(self, dir): - self.dir = dir - - def files(self): - os.chdir(self.dir) - for name in glob.glob('*.jpg'): - yield open(name) - -Instances of this class could then be registered with one or more spec id: - -.. code-block:: python - - from imagekit import register - - register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) - -Running the "generateimages" management command would now cause thumbnails to be -generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the -JPEGs in `/path/to/some/pics`. - -Note that, since this source group doesnt send the `source_created` or -`source_changed` signals, the corresponding cache file strategy callbacks -would not be called for them. diff --git a/docs/apireference.rst b/docs/apireference.rst deleted file mode 100644 index d4a2ed83..00000000 --- a/docs/apireference.rst +++ /dev/null @@ -1,29 +0,0 @@ -API Reference -============= - - -:mod:`models` Module --------------------- - -.. automodule:: imagekit.models.fields - :members: - - -:mod:`processors` Module ------------------------- - -.. automodule:: imagekit.processors - :members: - -.. automodule:: imagekit.processors.resize - :members: - -.. automodule:: imagekit.processors.crop - :members: - - -:mod:`admin` Module --------------------- - -.. automodule:: imagekit.admin - :members: diff --git a/docs/configuration.rst b/docs/configuration.rst index 18b3595e..62161587 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -10,7 +10,7 @@ Settings .. currentmodule:: django.conf.settings -.. attribute:: IMAGEKIT_CACHE_DIR +.. attribute:: IMAGEKIT_CACHEFILE_DIR :default: ``'CACHE/images'`` @@ -27,16 +27,16 @@ Settings will be used. -.. attribute:: IMAGEKIT_DEFAULT_IMAGE_CACHE_BACKEND +.. attribute:: IMAGEKIT_DEFAULT_CACHEFILE_BACKEND - :default: ``'imagekit.imagecache.backends.Simple'`` + :default: ``'imagekit.cachefiles.backends.Simple'`` Specifies the class that will be used to validate cached image files. -.. attribute:: IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY +.. attribute:: IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY - :default: ``'imagekit.imagecache.strategies.JustInTime'`` + :default: ``'imagekit.cachefiles.strategies.JustInTime'`` The class responsible for specifying how and when cache files are generated. @@ -58,80 +58,17 @@ Settings A cache prefix to be used when values are stored in ``IMAGEKIT_CACHE_BACKEND`` -Optimization ------------- +.. attribute:: IMAGEKIT_CACHEFILE_NAMER -Not surprisingly, the trick to getting the most out of ImageKit is to reduce the -number of I/O operations. This can be especially important if your source files -aren't stored on the same server as the application. + :default: ``'imagekit.cachefiles.namers.hash'`` + A function responsible for generating file names for non-spec cache files. -Image Cache Strategies -^^^^^^^^^^^^^^^^^^^^^^ -An important way of reducing the number of I/O operations that ImageKit makes is -by controlling when cached images are validated. This is done through "image -cache strategies"—objects that associate signals dispatched on the source file -with file actions. The default image cache strategy is -``'imagekit.imagecache.strategies.JustInTime'``; it looks like this: +.. attribute:: IMAGEKIT_SPEC_CACHEFILE_NAMER -.. code-block:: python + :default: ``'imagekit.cachefiles.namers.source_name_as_path'`` - class JustInTime(object): - def before_access(self, file): - validate_now(file) - -When this strategy is used, the cache file is validated only immediately before -it's required—for example, when you access its url, path, or contents. This -strategy is exceedingly safe: by guaranteeing the presence of the file before -accessing it, you run no risk of it not being there. However, this strategy can -also be costly: verifying the existence of the cache file every time you access -it can be slow—particularly if the file is on another server. For this reason, -ImageKit provides another strategy: ``imagekit.imagecache.strategies.Optimistic``. -Unlike the just-in-time strategy, it does not validate the cache file when it's -accessed, but rather only when the soure file is created or changed. Later, when -the cache file is accessed, it is presumed to still be present. - -If neither of these strategies suits your application, you can create your own -strategy class. For example, you may wish to validate the file immediately when -it's accessed, but schedule validation using Celery when the source file is -saved or changed: - -.. code-block:: python - - from imagekit.imagecache.actions import validate_now, deferred_validate - - class CustomImageCacheStrategy(object): - - def before_access(self, file): - validate_now(file) - - def on_source_created(self, file): - deferred_validate(file) - - def on_source_changed(self, file): - deferred_validate(file) - -To use this cache strategy, you need only set the ``IMAGEKIT_DEFAULT_IMAGE_CACHE_STRATEGY`` -setting, or set the ``image_cache_strategy`` attribute of your image spec. - - -Django Cache Backends -^^^^^^^^^^^^^^^^^^^^^ - -In the "Image Cache Strategies" section above, we said that the just-in-time -strategy verifies the existence of the cache file every time you access -it, however, that's not exactly true. Cache files are actually validated using -image cache backends, and the default (``imagekit.imagecache.backends.Simple``) -memoizes the cache state (valid or invalid) using Django's cache framework. By -default, ImageKit will use a dummy cache backend when your project is in debug -mode (``DEBUG = True``), and the "default" cache (from your ``CACHES`` setting) -when ``DEBUG`` is ``False``. Since other parts of your project may have -different cacheing needs, though, ImageKit has an ``IMAGEKIT_CACHE_BACKEND`` -setting, which allows you to specify a different cache. - -In most cases, you won't be deleting you cached files once they're created, so -using a cache with a large timeout is a great way to optimize your site. Using -a cache that never expires would essentially negate the cost of the just-in-time -strategy, giving you the benefit of generating images on demand without the cost -of unnecessary future filesystem checks. + A function responsible for generating file names for cache files that + correspond to image specs. Since you will likely want to base the name of + your cache files on the name of the source, this extra setting is provided. diff --git a/docs/index.rst b/docs/index.rst index 54843519..04eee0f4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,44 +1,24 @@ -Getting Started -=============== - .. include:: ../README.rst -Commands --------- - -.. automodule:: imagekit.management.commands.ikcacheinvalidate - -.. automodule:: imagekit.management.commands.ikcachevalidate - - Authors -------- +======= .. include:: ../AUTHORS -Community ---------- - -The official Freenode channel for ImageKit is `#imagekit `_. -You should always find some fine people to answer your questions -about ImageKit there. - - -Digging Deeper --------------- - -.. toctree:: - - configuration - apireference - changelog - - Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` + +.. toctree:: + :glob: + :maxdepth: 2 + + configuration + advanced_usage + changelog + upgrading diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 7a9b4386..4efe7c0a 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -5,6 +5,7 @@ ImageKit 3.0 introduces new APIs and tools that augment, improve, and in some cases entirely replace old IK workflows. Below, you'll find some useful guides for migrating your ImageKit 2.0 apps over to the shiny new IK3. + Model Specs ----------- From 088b84627b269c3eb4de613384e6d1101fb7164a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 5 Feb 2013 21:19:35 -0500 Subject: [PATCH 207/527] Add section about management commands --- README.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.rst b/README.rst index 2f2ad5d1..4263e8cd 100644 --- a/README.rst +++ b/README.rst @@ -392,6 +392,14 @@ AdminThumbnail can even use a custom template. For more information, see .. _`Django admin change list`: https://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-change-list +Managment Commands +------------------ + +ImageKit has one management command—`generateimages`—which will generate cache +files for all of your registered image generators. You can also pass it a list +of generator ids in order to generate images selectively. + + Community ========= From f6ce251e13415644b8975c974bf33fd074411726 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 20:40:54 -0500 Subject: [PATCH 208/527] Fix setup.py test --- setup.py | 14 +++++++++++++- testrunner.py | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 testrunner.py diff --git a/setup.py b/setup.py index 7c1495e3..209d6833 100644 --- a/setup.py +++ b/setup.py @@ -1,21 +1,31 @@ #/usr/bin/env python import codecs import os +from setuptools import setup, find_packages import sys -from setuptools import setup, find_packages + +# Workaround for multiprocessing/nose issue. See http://bugs.python.org/msg170215 +try: + import multiprocessing +except ImportError: + pass + if 'publish' in sys.argv: os.system('python setup.py sdist upload') sys.exit() + read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read() + # Load package meta from the pkgmeta module without loading imagekit. pkgmeta = {} execfile(os.path.join(os.path.dirname(__file__), 'imagekit', 'pkgmeta.py'), pkgmeta) + setup( name='django-imagekit', version=pkgmeta['__version__'], @@ -35,7 +45,9 @@ 'nose==1.2.1', 'nose-progressive==1.3', 'django-nose==1.1', + 'PIL==1.1.7', ], + test_suite='testrunner.run_tests', install_requires=[ 'django-appconf>=0.5', ], diff --git a/testrunner.py b/testrunner.py new file mode 100644 index 00000000..e4d27c77 --- /dev/null +++ b/testrunner.py @@ -0,0 +1,19 @@ +# A wrapper for Django's test runner. +# See http://ericholscher.com/blog/2009/jun/29/enable-setuppy-test-your-django-apps/ +# and http://gremu.net/blog/2010/enable-setuppy-test-your-django-apps/ +import os +import sys + +os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' +test_dir = os.path.dirname(__file__) +sys.path.insert(0, test_dir) + +from django.test.utils import get_runner +from django.conf import settings + + +def run_tests(): + cls = get_runner(settings) + runner = cls() + failures = runner.run_tests(['tests']) + sys.exit(failures) From 5982e1e549067b962269b924fa543831a376edfb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 20:41:18 -0500 Subject: [PATCH 209/527] Remove Makefile --- Makefile | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index 3ec6c464..00000000 --- a/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -test: - flake8 --ignore=E501,E126,E127,E128 imagekit tests - export PYTHONPATH=$(PWD):$(PYTHONPATH); \ - django-admin.py test --settings=tests.settings tests - - -.PHONY: test From c90e6d637c6c3a8618188d5c519c62d751041710 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 20:46:06 -0500 Subject: [PATCH 210/527] Simplify tox command --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5a5e2e7d..80c5fd19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,6 @@ language: python python: - 2.7 install: pip install tox --use-mirrors -script: tox -e py27-django13,py27-django12,py26-django13,py27-django12 +script: tox notifications: irc: "irc.freenode.org#imagekit" From 7759394df73387e332ab99874652c031154da599 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 20:46:14 -0500 Subject: [PATCH 211/527] Remove Pillow (PIL is specified in setup.py) --- tox.ini | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tox.ini b/tox.ini index cedd0d1e..c7c54cfd 100644 --- a/tox.ini +++ b/tox.ini @@ -4,40 +4,34 @@ envlist = py26-django14, py26-django13, py26-django12 [testenv] -commands = make test +commands = python setup.py test [testenv:py27-django14] basepython = python2.7 deps = Django>=1.4,<1.5 - Pillow [testenv:py27-django13] basepython = python2.7 deps = Django>=1.3,<1.4 - Pillow [testenv:py27-django12] basepython = python2.7 deps = Django>=1.2,<1.3 - Pillow [testenv:py26-django14] basepython = python2.6 deps = Django>=1.4,<1.5 - Pillow [testenv:py26-django13] basepython = python2.6 deps = Django>=1.3,<1.4 - Pillow [testenv:py26-django12] basepython = python2.6 deps = Django>=1.2,<1.3 - Pillow From 4ac6565bec4278b14d224cd8a267a9e464f4486f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 21:01:51 -0500 Subject: [PATCH 212/527] Use Pillow for testing --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 209d6833..61cc5466 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ 'nose==1.2.1', 'nose-progressive==1.3', 'django-nose==1.1', - 'PIL==1.1.7', + 'Pillow==1.7.8', ], test_suite='testrunner.run_tests', install_requires=[ From 51dcf283fda1492d8e75da2c036848ab4149030d Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 21:59:26 -0500 Subject: [PATCH 213/527] Fix default cache backend for Django < 1.3 --- imagekit/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 3abd6f37..4c2f2e77 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -16,5 +16,8 @@ class ImageKitConf(AppConf): def configure_cache_backend(self, value): if value is None: - value = 'django.core.cache.backends.dummy.DummyCache' if settings.DEBUG else 'default' + if getattr(settings, 'CACHES', None): + value = 'django.core.cache.backends.dummy.DummyCache' if settings.DEBUG else 'default' + else: + value = 'dummy://' if settings.DEBUG else settings.CACHE_BACKEND return value From 561856abd79d785cb8d1a4e1580c735f68531fd2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 22:04:13 -0500 Subject: [PATCH 214/527] Don't use assert_not_in It's not available in Python 2.6 --- tests/test_generateimage_tag.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_generateimage_tag.py b/tests/test_generateimage_tag.py index e7ea0915..c39b7944 100644 --- a/tests/test_generateimage_tag.py +++ b/tests/test_generateimage_tag.py @@ -1,5 +1,5 @@ from django.template import TemplateSyntaxError -from nose.tools import eq_, assert_not_in, raises, assert_not_equal +from nose.tools import eq_, assert_false, raises, assert_not_equal from . import imagegenerators # noqa from .utils import render_tag, get_html_attrs @@ -43,7 +43,7 @@ def test_single_dimension_attr(): """ ttag = r"""{% generateimage 'testspec' source=img -- width="50" %}""" attrs = get_html_attrs(ttag) - assert_not_in('height', attrs) + assert_false('height' in attrs) def test_assignment_tag(): From 8fabbae86cbddc6d4a256787e4592e426fddf68e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 6 Feb 2013 22:21:20 -0500 Subject: [PATCH 215/527] Extract version from pkgmeta --- docs/conf.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index e0913b92..35f184d7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import re, sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -45,14 +45,18 @@ project = u'ImageKit' copyright = u'2011, Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett & Matthew Tretter' +pkgmeta = {} +execfile(os.path.join(os.path.dirname(__file__), '..', 'imagekit', + 'pkgmeta.py'), pkgmeta) + # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '2.0.2' +version = re.match('\d+\.\d+', pkgmeta['__version__']).group() # The full version, including alpha/beta/rc tags. -release = '2.0.2' +release = pkgmeta['__version__'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. From d0ba353be3d746059bbe24c25921ffeb7efa0a8e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 7 Feb 2013 16:11:02 -0500 Subject: [PATCH 216/527] Typo fix! --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 4263e8cd..5e670deb 100644 --- a/README.rst +++ b/README.rst @@ -392,8 +392,8 @@ AdminThumbnail can even use a custom template. For more information, see .. _`Django admin change list`: https://docs.djangoproject.com/en/dev/intro/tutorial02/#customize-the-admin-change-list -Managment Commands ------------------- +Management Commands +------------------- ImageKit has one management command—`generateimages`—which will generate cache files for all of your registered image generators. You can also pass it a list From 36313194ac9a7436ac3a541aa06d22dccabd3651 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 7 Feb 2013 23:10:05 -0500 Subject: [PATCH 217/527] Remove PILKit functionality This commit removes the functionality now in the PILKit project, and adds PILKit as a dependency. Import hooks have been used to expose the processors under "imagekit.processors". --- imagekit/__init__.py | 2 +- imagekit/exceptions.py | 14 +- imagekit/importers.py | 29 +++ imagekit/processors/__init__.py | 15 -- imagekit/processors/base.py | 209 ---------------------- imagekit/processors/crop.py | 170 ------------------ imagekit/processors/resize.py | 260 --------------------------- imagekit/processors/utils.py | 18 -- imagekit/utils.py | 301 +------------------------------- setup.py | 1 + 10 files changed, 39 insertions(+), 980 deletions(-) create mode 100644 imagekit/importers.py delete mode 100644 imagekit/processors/__init__.py delete mode 100644 imagekit/processors/base.py delete mode 100644 imagekit/processors/crop.py delete mode 100644 imagekit/processors/resize.py delete mode 100644 imagekit/processors/utils.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index e65c2707..d78a1300 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,5 +1,5 @@ # flake8: noqa - +from . import importers from . import conf from . import generatorlibrary from .specs import ImageSpec diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index 308c0a17..0c46514e 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -1,18 +1,18 @@ -class AlreadyRegistered(Exception): - pass +from pilkit.exceptions import UnknownExtension, UnknownFormat -class NotRegistered(Exception): +class AlreadyRegistered(Exception): pass -class UnknownExtensionError(Exception): +class NotRegistered(Exception): pass -class UnknownFormatError(Exception): +class MissingGeneratorId(Exception): pass -class MissingGeneratorId(Exception): - pass +# Aliases for backwards compatibility +UnknownExtensionError = UnknownExtension +UnknownFormatError = UnknownFormat diff --git a/imagekit/importers.py b/imagekit/importers.py new file mode 100644 index 00000000..cddcd838 --- /dev/null +++ b/imagekit/importers.py @@ -0,0 +1,29 @@ +from django.utils.importlib import import_module +import re +import sys + + +class ProcessorImporter(object): + """ + The processors were moved to the PILKit project so they could be used + separtely from ImageKit (which has a bunch of Django dependencies). However, + there's no real need to expose this fact (and we want to maintain backwards + compatibility), so we proxy all "imagekit.processors" imports to + "pilkit.processors" using this object. + + """ + pattern = re.compile(r'^imagekit\.processors((\..*)?)$') + + def find_module(self, name, path=None): + if self.pattern.match(name): + return self + + def load_module(self, name): + if name in sys.modules: + return sys.modules[name] + + new_name = self.pattern.sub(r'pilkit.processors\1', name) + return import_module(new_name) + + +sys.meta_path.append(ProcessorImporter()) diff --git a/imagekit/processors/__init__.py b/imagekit/processors/__init__.py deleted file mode 100644 index 6c8d0b7b..00000000 --- a/imagekit/processors/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# flake8: noqa - -""" -Imagekit image processors. - -A processor accepts an image, does some stuff, and returns the result. -Processors can do anything with the image you want, but their responsibilities -should be limited to image manipulations--they should be completely decoupled -from both the filesystem and the ORM. - -""" - -from .base import * -from .crop import * -from .resize import * diff --git a/imagekit/processors/base.py b/imagekit/processors/base.py deleted file mode 100644 index 61c0e30a..00000000 --- a/imagekit/processors/base.py +++ /dev/null @@ -1,209 +0,0 @@ -from imagekit.lib import Image, ImageColor, ImageEnhance - - -class ProcessorPipeline(list): - """ - A :class:`list` of other processors. This class allows any object that - knows how to deal with a single processor to deal with a list of them. - For example:: - - processed_image = ProcessorPipeline([ProcessorA(), ProcessorB()]).process(image) - - """ - def process(self, img): - for proc in self: - img = proc.process(img) - return img - - -class Adjust(object): - """ - Performs color, brightness, contrast, and sharpness enhancements on the - image. See :mod:`PIL.ImageEnhance` for more imformation. - - """ - def __init__(self, color=1.0, brightness=1.0, contrast=1.0, sharpness=1.0): - """ - :param color: A number between 0 and 1 that specifies the saturation - of the image. 0 corresponds to a completely desaturated image - (black and white) and 1 to the original color. - See :class:`PIL.ImageEnhance.Color` - :param brightness: A number representing the brightness; 0 results in - a completely black image whereas 1 corresponds to the brightness - of the original. See :class:`PIL.ImageEnhance.Brightness` - :param contrast: A number representing the contrast; 0 results in a - completely gray image whereas 1 corresponds to the contrast of - the original. See :class:`PIL.ImageEnhance.Contrast` - :param sharpness: A number representing the sharpness; 0 results in a - blurred image; 1 corresponds to the original sharpness; 2 - results in a sharpened image. See - :class:`PIL.ImageEnhance.Sharpness` - - """ - self.color = color - self.brightness = brightness - self.contrast = contrast - self.sharpness = sharpness - - def process(self, img): - original = img = img.convert('RGBA') - for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']: - factor = getattr(self, name.lower()) - if factor != 1.0: - try: - img = getattr(ImageEnhance, name)(img).enhance(factor) - except ValueError: - pass - else: - # PIL's Color and Contrast filters both convert the image - # to L mode, losing transparency info, so we put it back. - # See https://github.com/jdriscoll/django-imagekit/issues/64 - if name in ('Color', 'Contrast'): - img = Image.merge('RGBA', img.split()[:3] + - original.split()[3:4]) - return img - - -class Reflection(object): - """ - Creates an image with a reflection. - - """ - def __init__(self, background_color='#FFFFFF', size=0.0, opacity=0.6): - self.background_color = background_color - self.size = size - self.opacity = opacity - - def process(self, img): - # Convert bgcolor string to RGB value. - background_color = ImageColor.getrgb(self.background_color) - # Handle palleted images. - img = img.convert('RGBA') - # Copy orignial image and flip the orientation. - reflection = img.copy().transpose(Image.FLIP_TOP_BOTTOM) - # Create a new image filled with the bgcolor the same size. - background = Image.new("RGBA", img.size, background_color) - # Calculate our alpha mask. - start = int(255 - (255 * self.opacity)) # The start of our gradient. - steps = int(255 * self.size) # The number of intermedite values. - increment = (255 - start) / float(steps) - mask = Image.new('L', (1, 255)) - for y in range(255): - if y < steps: - val = int(y * increment + start) - else: - val = 255 - mask.putpixel((0, y), val) - alpha_mask = mask.resize(img.size) - # Merge the reflection onto our background color using the alpha mask. - reflection = Image.composite(background, reflection, alpha_mask) - # Crop the reflection. - reflection_height = int(img.size[1] * self.size) - reflection = reflection.crop((0, 0, img.size[0], reflection_height)) - # Create new image sized to hold both the original image and - # the reflection. - composite = Image.new("RGBA", (img.size[0], img.size[1] + reflection_height), background_color) - # Paste the orignal image and the reflection into the composite image. - composite.paste(img, (0, 0)) - composite.paste(reflection, (0, img.size[1])) - # Return the image complete with reflection effect. - return composite - - -class Transpose(object): - """ - Rotates or flips the image. - - """ - AUTO = 'auto' - FLIP_HORIZONTAL = Image.FLIP_LEFT_RIGHT - FLIP_VERTICAL = Image.FLIP_TOP_BOTTOM - ROTATE_90 = Image.ROTATE_90 - ROTATE_180 = Image.ROTATE_180 - ROTATE_270 = Image.ROTATE_270 - - methods = [AUTO] - _EXIF_ORIENTATION_STEPS = { - 1: [], - 2: [FLIP_HORIZONTAL], - 3: [ROTATE_180], - 4: [FLIP_VERTICAL], - 5: [ROTATE_270, FLIP_HORIZONTAL], - 6: [ROTATE_270], - 7: [ROTATE_90, FLIP_HORIZONTAL], - 8: [ROTATE_90], - } - - def __init__(self, *args): - """ - Possible arguments: - - Transpose.AUTO - - Transpose.FLIP_HORIZONTAL - - Transpose.FLIP_VERTICAL - - Transpose.ROTATE_90 - - Transpose.ROTATE_180 - - Transpose.ROTATE_270 - - The order of the arguments dictates the order in which the - Transposition steps are taken. - - If Transpose.AUTO is present, all other arguments are ignored, and - the processor will attempt to rotate the image according to the - EXIF Orientation data. - - """ - super(Transpose, self).__init__() - if args: - self.methods = args - - def process(self, img): - if self.AUTO in self.methods: - try: - orientation = img._getexif()[0x0112] - ops = self._EXIF_ORIENTATION_STEPS[orientation] - except (KeyError, TypeError, AttributeError): - ops = [] - else: - ops = self.methods - for method in ops: - img = img.transpose(method) - return img - - -class Anchor(object): - """ - Defines all the anchor points needed by the various processor classes. - - """ - TOP_LEFT = 'tl' - TOP = 't' - TOP_RIGHT = 'tr' - BOTTOM_LEFT = 'bl' - BOTTOM = 'b' - BOTTOM_RIGHT = 'br' - CENTER = 'c' - LEFT = 'l' - RIGHT = 'r' - - _ANCHOR_PTS = { - TOP_LEFT: (0, 0), - TOP: (0.5, 0), - TOP_RIGHT: (1, 0), - LEFT: (0, 0.5), - CENTER: (0.5, 0.5), - RIGHT: (1, 0.5), - BOTTOM_LEFT: (0, 1), - BOTTOM: (0.5, 1), - BOTTOM_RIGHT: (1, 1), - } - - @staticmethod - def get_tuple(anchor): - """Normalizes anchor values (strings or tuples) to tuples. - - """ - # If the user passed in one of the string values, convert it to a - # percentage tuple. - if anchor in Anchor._ANCHOR_PTS.keys(): - anchor = Anchor._ANCHOR_PTS[anchor] - return anchor diff --git a/imagekit/processors/crop.py b/imagekit/processors/crop.py deleted file mode 100644 index b039d302..00000000 --- a/imagekit/processors/crop.py +++ /dev/null @@ -1,170 +0,0 @@ -from .base import Anchor # noqa -from .utils import histogram_entropy -from ..lib import Image, ImageChops, ImageDraw, ImageStat - - -class Side(object): - TOP = 't' - RIGHT = 'r' - BOTTOM = 'b' - LEFT = 'l' - ALL = (TOP, RIGHT, BOTTOM, LEFT) - - -def _crop(img, bbox, sides=Side.ALL): - bbox = ( - bbox[0] if Side.LEFT in sides else 0, - bbox[1] if Side.TOP in sides else 0, - bbox[2] if Side.RIGHT in sides else img.size[0], - bbox[3] if Side.BOTTOM in sides else img.size[1], - ) - return img.crop(bbox) - - -def detect_border_color(img): - mask = Image.new('1', img.size, 1) - w, h = img.size[0] - 2, img.size[1] - 2 - if w > 0 and h > 0: - draw = ImageDraw.Draw(mask) - draw.rectangle([1, 1, w, h], 0) - return ImageStat.Stat(img.convert('RGBA').histogram(mask)).median - - -class TrimBorderColor(object): - """Trims a color from the sides of an image. - - """ - def __init__(self, color=None, tolerance=0.3, sides=Side.ALL): - """ - :param color: The color to trim from the image, in a 4-tuple RGBA value, - where each component is an integer between 0 and 255, inclusive. If - no color is provided, the processor will attempt to detect the - border color automatically. - :param tolerance: A number between 0 and 1 where 0. Zero is the least - tolerant and one is the most. - :param sides: A list of sides that should be trimmed. Possible values - are provided by the :class:`Side` enum class. - - """ - self.color = color - self.sides = sides - self.tolerance = tolerance - - def process(self, img): - source = img.convert('RGBA') - border_color = self.color or tuple(detect_border_color(source)) - bg = Image.new('RGBA', img.size, border_color) - diff = ImageChops.difference(source, bg) - if self.tolerance not in (0, 1): - # If tolerance is zero, we've already done the job. A tolerance of - # one would mean to trim EVERY color, and since that would result - # in a zero-sized image, we just ignore it. - if not 0 <= self.tolerance <= 1: - raise ValueError('%s is an invalid tolerance. Acceptable values' - ' are between 0 and 1 (inclusive).' % self.tolerance) - tmp = ImageChops.constant(diff, int(self.tolerance * 255)) \ - .convert('RGBA') - diff = ImageChops.subtract(diff, tmp) - - bbox = diff.getbbox() - if bbox: - img = _crop(img, bbox, self.sides) - return img - - -class Crop(object): - """ - Crops an image, cropping it to the specified width and height. You may - optionally provide either an anchor or x and y coordinates. This processor - functions exactly the same as ``ResizeCanvas`` except that it will never - enlarge the image. - - """ - - def __init__(self, width=None, height=None, anchor=None, x=None, y=None): - self.width = width - self.height = height - self.anchor = anchor - self.x = x - self.y = y - - def process(self, img): - from .resize import ResizeCanvas - - original_width, original_height = img.size - new_width, new_height = min(original_width, self.width), \ - min(original_height, self.height) - - return ResizeCanvas(new_width, new_height, anchor=self.anchor, - x=self.x, y=self.y).process(img) - - -class SmartCrop(object): - """ - Crop an image to the specified dimensions, whittling away the parts of the - image with the least entropy. - - Based on smart crop implementation from easy-thumbnails: - https://github.com/SmileyChris/easy-thumbnails/blob/master/easy_thumbnails/processors.py#L193 - - """ - - def __init__(self, width=None, height=None): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - - """ - self.width = width - self.height = height - - def compare_entropy(self, start_slice, end_slice, slice, difference): - """ - Calculate the entropy of two slices (from the start and end of an axis), - returning a tuple containing the amount that should be added to the start - and removed from the end of the axis. - - """ - start_entropy = histogram_entropy(start_slice) - end_entropy = histogram_entropy(end_slice) - - if end_entropy and abs(start_entropy / end_entropy - 1) < 0.01: - # Less than 1% difference, remove from both sides. - if difference >= slice * 2: - return slice, slice - half_slice = slice // 2 - return half_slice, slice - half_slice - - if start_entropy > end_entropy: - return 0, slice - else: - return slice, 0 - - def process(self, img): - source_x, source_y = img.size - diff_x = int(source_x - min(source_x, self.width)) - diff_y = int(source_y - min(source_y, self.height)) - left = top = 0 - right, bottom = source_x, source_y - - while diff_x: - slice = min(diff_x, max(diff_x // 5, 10)) - start = img.crop((left, 0, left + slice, source_y)) - end = img.crop((right - slice, 0, right, source_y)) - add, remove = self.compare_entropy(start, end, slice, diff_x) - left += add - right -= remove - diff_x = diff_x - add - remove - - while diff_y: - slice = min(diff_y, max(diff_y // 5, 10)) - start = img.crop((0, top, source_x, top + slice)) - end = img.crop((0, bottom - slice, source_x, bottom)) - add, remove = self.compare_entropy(start, end, slice, diff_y) - top += add - bottom -= remove - diff_y = diff_y - add - remove - - box = (left, top, right, bottom) - img = img.crop(box) - return img diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py deleted file mode 100644 index 0bae1225..00000000 --- a/imagekit/processors/resize.py +++ /dev/null @@ -1,260 +0,0 @@ -from imagekit.lib import Image -from .base import Anchor - - -class Resize(object): - """ - Resizes an image to the specified width and height. - - """ - def __init__(self, width, height): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - - """ - self.width = width - self.height = height - - def process(self, img): - return img.resize((self.width, self.height), Image.ANTIALIAS) - - -class ResizeToCover(object): - """ - Resizes the image to the smallest possible size that will entirely cover the - provided dimensions. You probably won't be using this processor directly, - but it's used internally by ``ResizeToFill`` and ``SmartResize``. - - """ - def __init__(self, width, height): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - - """ - self.width, self.height = width, height - - def process(self, img): - original_width, original_height = img.size - ratio = max(float(self.width) / original_width, - float(self.height) / original_height) - new_width, new_height = (int(original_width * ratio), - int(original_height * ratio)) - return Resize(new_width, new_height).process(img) - - -class ResizeToFill(object): - """ - Resizes an image, cropping it to the exact specified width and height. - - """ - - def __init__(self, width=None, height=None, anchor=None): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - :param anchor: Specifies which part of the image should be retained - when cropping. - """ - self.width = width - self.height = height - self.anchor = anchor - - def process(self, img): - from .crop import Crop - img = ResizeToCover(self.width, self.height).process(img) - return Crop(self.width, self.height, - anchor=self.anchor).process(img) - - -class SmartResize(object): - """ - The ``SmartResize`` processor is identical to ``ResizeToFill``, except that - it uses entropy to crop the image instead of a user-specified anchor point. - Internally, it simply runs the ``ResizeToCover`` and ``SmartCrop`` - processors in series. - """ - def __init__(self, width, height): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - - """ - self.width, self.height = width, height - - def process(self, img): - from .crop import SmartCrop - img = ResizeToCover(self.width, self.height).process(img) - return SmartCrop(self.width, self.height).process(img) - - -class ResizeCanvas(object): - """ - Resizes the canvas, using the provided background color if the new size is - larger than the current image. - - """ - def __init__(self, width, height, color=None, anchor=None, x=None, y=None): - """ - :param width: The target width, in pixels. - :param height: The target height, in pixels. - :param color: The background color to use for padding. - :param anchor: Specifies the position of the original image on the new - canvas. Valid values are: - - - Anchor.TOP_LEFT - - Anchor.TOP - - Anchor.TOP_RIGHT - - Anchor.LEFT - - Anchor.CENTER - - Anchor.RIGHT - - Anchor.BOTTOM_LEFT - - Anchor.BOTTOM - - Anchor.BOTTOM_RIGHT - - You may also pass a tuple that indicates the position in - percentages. For example, ``(0, 0)`` corresponds to "top left", - ``(0.5, 0.5)`` to "center" and ``(1, 1)`` to "bottom right". This is - basically the same as using percentages in CSS background positions. - - """ - if x is not None or y is not None: - if anchor: - raise Exception('You may provide either an anchor or x and y' - ' coordinate, but not both.') - else: - self.x, self.y = x or 0, y or 0 - self.anchor = None - else: - self.anchor = anchor or Anchor.CENTER - self.x = self.y = None - - self.width = width - self.height = height - self.color = color or (255, 255, 255, 0) - - def process(self, img): - original_width, original_height = img.size - - if self.anchor: - anchor = Anchor.get_tuple(self.anchor) - trim_x, trim_y = self.width - original_width, \ - self.height - original_height - x = int(float(trim_x) * float(anchor[0])) - y = int(float(trim_y) * float(anchor[1])) - else: - x, y = self.x, self.y - - new_img = Image.new('RGBA', (self.width, self.height), self.color) - new_img.paste(img, (x, y)) - return new_img - - -class AddBorder(object): - """ - Add a border of specific color and size to an image. - - """ - def __init__(self, thickness, color=None): - """ - :param color: Color to use for the border - :param thickness: Thickness of the border. Can be either an int or - a 4-tuple of ints of the form (top, right, bottom, left). - """ - self.color = color - if isinstance(thickness, int): - self.top = self.right = self.bottom = self.left = thickness - else: - self.top, self.right, self.bottom, self.left = thickness - - def process(self, img): - new_width = img.size[0] + self.left + self.right - new_height = img.size[1] + self.top + self.bottom - return ResizeCanvas(new_width, new_height, color=self.color, - x=self.left, y=self.top).process(img) - - -class ResizeToFit(object): - """ - Resizes an image to fit within the specified dimensions. - - """ - - def __init__(self, width=None, height=None, upscale=None, mat_color=None, anchor=Anchor.CENTER): - """ - :param width: The maximum width of the desired image. - :param height: The maximum height of the desired image. - :param upscale: A boolean value specifying whether the image should - be enlarged if its dimensions are smaller than the target - dimensions. - :param mat_color: If set, the target image size will be enforced and the - specified color will be used as a background color to pad the image. - - """ - self.width = width - self.height = height - self.upscale = upscale - self.mat_color = mat_color - self.anchor = anchor - - def process(self, img): - cur_width, cur_height = img.size - if not self.width is None and not self.height is None: - ratio = min(float(self.width) / cur_width, - float(self.height) / cur_height) - else: - if self.width is None: - ratio = float(self.height) / cur_height - else: - ratio = float(self.width) / cur_width - new_dimensions = (int(round(cur_width * ratio)), - int(round(cur_height * ratio))) - if (cur_width > new_dimensions[0] or cur_height > new_dimensions[1]) or self.upscale: - img = Resize(new_dimensions[0], new_dimensions[1]).process(img) - if self.mat_color is not None: - img = ResizeCanvas(self.width, self.height, self.mat_color, anchor=self.anchor).process(img) - return img - - -class Thumbnail(object): - """ - Resize the image for use as a thumbnail. Wraps ``ResizeToFill``, - ``ResizeToFit``, and ``SmartResize``. - - Note: while it doesn't currently, in the future this processor may also - sharpen based on the amount of reduction. - - """ - - def __init__(self, width=None, height=None, anchor=None, crop=None): - self.width = width - self.height = height - if anchor: - if crop is False: - raise Exception("You can't specify an anchor point if crop is False.") - else: - crop = True - elif crop is None: - # Assume we are cropping if both a width and height are provided. If - # only one is, we must be resizing to fit. - crop = width is not None and height is not None - - # A default anchor if cropping. - if crop and anchor is None: - anchor = 'auto' - self.crop = crop - self.anchor = anchor - - def process(self, img): - if self.crop: - if not self.width or not self.height: - raise Exception('You must provide both a width and height when' - ' cropping.') - if self.anchor == 'auto': - processor = SmartResize(self.width, self.height) - else: - processor = ResizeToFill(self.width, self.height, self.anchor) - else: - processor = ResizeToFit(self.width, self.height) - return processor.process(img) diff --git a/imagekit/processors/utils.py b/imagekit/processors/utils.py deleted file mode 100644 index db244dbd..00000000 --- a/imagekit/processors/utils.py +++ /dev/null @@ -1,18 +0,0 @@ -import math -from imagekit.lib import Image - - -def histogram_entropy(im): - """ - Calculate the entropy of an images' histogram. Used for "smart cropping" in easy-thumbnails; - see: https://raw.github.com/SmileyChris/easy-thumbnails/master/easy_thumbnails/utils.py - - """ - if not isinstance(im, Image.Image): - return 0 # Fall back to a constant entropy. - - histogram = im.histogram() - hist_ceil = float(sum(histogram)) - histonorm = [histocol / hist_ceil for histocol in histogram] - - return -sum([p * math.log(p, 2) for p in histonorm if p != 0]) diff --git a/imagekit/utils.py b/imagekit/utils.py index ff02a50a..6f4fd525 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,26 +1,11 @@ import logging -import os -import mimetypes -import sys from tempfile import NamedTemporaryFile -import types from django.core.exceptions import ImproperlyConfigured from django.core.files import File from django.db.models.loading import cache -from django.utils.functional import wraps from django.utils.importlib import import_module - -from .exceptions import UnknownExtensionError, UnknownFormatError -from .lib import Image, ImageFile, StringIO - - -RGBA_TRANSPARENCY_FORMATS = ['PNG'] -PALETTE_TRANSPARENCY_FORMATS = ['PNG', 'GIF'] - - -def img_to_fobj(img, format, autoconvert=True, **options): - return save_image(img, StringIO(), format, options, autoconvert) +from pilkit.utils import * def get_spec_files(instance): @@ -30,116 +15,6 @@ def get_spec_files(instance): return [] -def open_image(target): - target.seek(0) - img = Image.open(target) - img.copy = types.MethodType(_wrap_copy(img.copy), img, img.__class__) - return img - - -def _wrap_copy(f): - @wraps(f) - def copy(self): - img = f() - try: - img.app = self.app - except AttributeError: - pass - try: - img._getexif = self._getexif - except AttributeError: - pass - return img - return copy - - -_pil_init = 0 - - -def _preinit_pil(): - """Loads the standard PIL file format drivers. Returns True if ``preinit()`` - was called (and there's a potential that more drivers were loaded) or False - if there is no possibility that new drivers were loaded. - - """ - global _pil_init - if _pil_init < 1: - Image.preinit() - _pil_init = 1 - return True - return False - - -def _init_pil(): - """Loads all PIL file format drivers. Returns True if ``init()`` was called - (and there's a potential that more drivers were loaded) or False if there is - no possibility that new drivers were loaded. - - """ - global _pil_init - _preinit_pil() - if _pil_init < 2: - Image.init() - _pil_init = 2 - return True - return False - - -def _extension_to_format(extension): - return Image.EXTENSION.get(extension.lower()) - - -def _format_to_extension(format): - if format: - for k, v in Image.EXTENSION.iteritems(): - if v == format.upper(): - return k - return None - - -def extension_to_mimetype(ext): - try: - filename = 'a%s' % (ext or '') # guess_type requires a full filename, not just an extension - mimetype = mimetypes.guess_type(filename)[0] - except IndexError: - mimetype = None - return mimetype - - -def format_to_mimetype(format): - return extension_to_mimetype(format_to_extension(format)) - - -def extension_to_format(extension): - """Returns the format that corresponds to the provided extension. - - """ - format = _extension_to_format(extension) - if not format and _preinit_pil(): - format = _extension_to_format(extension) - if not format and _init_pil(): - format = _extension_to_format(extension) - if not format: - raise UnknownExtensionError(extension) - return format - - -def format_to_extension(format): - """Returns the first extension that matches the provided format. - - """ - extension = None - if format: - extension = _format_to_extension(format) - if not extension and _preinit_pil(): - extension = _format_to_extension(format) - if not extension and _init_pil(): - extension = _format_to_extension(format) - if not extension: - raise UnknownFormatError(format) - return extension - - def _get_models(apps): models = [] for app_label in apps or []: @@ -148,180 +23,6 @@ def _get_models(apps): return models -def suggest_extension(name, format): - original_extension = os.path.splitext(name)[1] - try: - suggested_extension = format_to_extension(format) - except UnknownFormatError: - extension = original_extension - else: - if suggested_extension.lower() == original_extension.lower(): - extension = original_extension - else: - try: - original_format = extension_to_format(original_extension) - except UnknownExtensionError: - extension = suggested_extension - else: - # If the formats match, give precedence to the original extension. - if format.lower() == original_format.lower(): - extension = original_extension - else: - extension = suggested_extension - return extension - - -def save_image(img, outfile, format, options=None, autoconvert=True): - """ - Wraps PIL's ``Image.save()`` method. There are two main benefits of using - this function over PIL's: - - 1. It gracefully handles the infamous "Suspension not allowed here" errors. - 2. It prepares the image for saving using ``prepare_image()``, which will do - some common-sense processing given the target format. - - """ - options = options or {} - - if autoconvert: - img, save_kwargs = prepare_image(img, format) - options = dict(save_kwargs.items() + options.items()) - - # Attempt to reset the file pointer. - try: - outfile.seek(0) - except AttributeError: - pass - - try: - with quiet(): - img.save(outfile, format, **options) - except IOError: - # PIL can have problems saving large JPEGs if MAXBLOCK isn't big enough, - # So if we have a problem saving, we temporarily increase it. See - # http://github.com/jdriscoll/django-imagekit/issues/50 - old_maxblock = ImageFile.MAXBLOCK - ImageFile.MAXBLOCK = img.size[0] * img.size[1] - try: - img.save(outfile, format, **options) - finally: - ImageFile.MAXBLOCK = old_maxblock - - try: - outfile.seek(0) - except AttributeError: - pass - - return outfile - - -class quiet(object): - """ - A context manager for suppressing the stderr activity of PIL's C libraries. - Based on http://stackoverflow.com/a/978264/155370 - - """ - def __enter__(self): - self.stderr_fd = sys.__stderr__.fileno() - self.null_fd = os.open(os.devnull, os.O_RDWR) - self.old = os.dup(self.stderr_fd) - os.dup2(self.null_fd, self.stderr_fd) - - def __exit__(self, *args, **kwargs): - os.dup2(self.old, self.stderr_fd) - os.close(self.null_fd) - os.close(self.old) - - -def prepare_image(img, format): - """ - Prepares the image for saving to the provided format by doing some - common-sense conversions. This includes things like preserving transparency - and quantizing. This function is used automatically by ``save_image()`` - (and classes like ``ImageSpecField`` and ``ProcessedImageField``) - immediately before saving unless you specify ``autoconvert=False``. It is - provided as a utility for those doing their own processing. - - :param img: The image to prepare for saving. - :param format: The format that the image will be saved to. - - """ - matte = False - save_kwargs = {} - - if img.mode == 'RGBA': - if format in RGBA_TRANSPARENCY_FORMATS: - pass - elif format in PALETTE_TRANSPARENCY_FORMATS: - # If you're going from a format with alpha transparency to one - # with palette transparency, transparency values will be - # snapped: pixels that are more opaque than not will become - # fully opaque; pixels that are more transparent than not will - # become fully transparent. This will not produce a good-looking - # result if your image contains varying levels of opacity; in - # that case, you'll probably want to use a processor to matte - # the image on a solid color. The reason we don't matte by - # default is because not doing so allows processors to treat - # RGBA-format images as a super-type of P-format images: if you - # have an RGBA-format image with only a single transparent - # color, and save it as a GIF, it will retain its transparency. - # In other words, a P-format image converted to an - # RGBA-formatted image by a processor and then saved as a - # P-format image will give the expected results. - - # Work around a bug in PIL: split() doesn't check to see if - # img is loaded. - img.load() - - alpha = img.split()[-1] - mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0) - img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, - colors=255) - img.paste(255, mask) - save_kwargs['transparency'] = 255 - else: - # Simply converting an RGBA-format image to an RGB one creates a - # gross result, so we matte the image on a white background. If - # that's not what you want, that's fine: use a processor to deal - # with the transparency however you want. This is simply a - # sensible default that will always produce something that looks - # good. Or at least, it will look better than just a straight - # conversion. - matte = True - elif img.mode == 'P': - if format in PALETTE_TRANSPARENCY_FORMATS: - try: - save_kwargs['transparency'] = img.info['transparency'] - except KeyError: - pass - elif format in RGBA_TRANSPARENCY_FORMATS: - # Currently PIL doesn't support any RGBA-mode formats that - # aren't also P-mode formats, so this will never happen. - img = img.convert('RGBA') - else: - matte = True - else: - img = img.convert('RGB') - - # GIFs are always going to be in palette mode, so we can do a little - # optimization. Note that the RGBA sources also use adaptive - # quantization (above). Images that are already in P mode don't need - # any quantization because their colors are already limited. - if format == 'GIF': - img = img.convert('P', palette=Image.ADAPTIVE) - - if matte: - img = img.convert('RGBA') - bg = Image.new('RGBA', img.size, (255, 255, 255)) - bg.paste(img, img) - img = bg.convert('RGB') - - if format == 'JPEG': - save_kwargs['optimize'] = True - - return img, save_kwargs - - def get_by_qname(path, desc): try: dot = path.rindex('.') diff --git a/setup.py b/setup.py index 61cc5466..9a16e877 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,7 @@ test_suite='testrunner.run_tests', install_requires=[ 'django-appconf>=0.5', + 'pilkit<2.0a0', ], classifiers=[ 'Development Status :: 5 - Production/Stable', From ec5d4ed324d904f02f41bcff1fdbb21a2fe6f8bc Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 7 Feb 2013 23:15:08 -0500 Subject: [PATCH 218/527] Remove processor tests; these are in PILKit --- tests/test_processors.py | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 tests/test_processors.py diff --git a/tests/test_processors.py b/tests/test_processors.py deleted file mode 100644 index 316b57ff..00000000 --- a/tests/test_processors.py +++ /dev/null @@ -1,31 +0,0 @@ -from imagekit.lib import Image -from imagekit.processors import ResizeToFill, ResizeToFit, SmartCrop -from nose.tools import eq_ -from .utils import create_image - - -def test_smartcrop(): - img = SmartCrop(100, 100).process(create_image()) - eq_(img.size, (100, 100)) - - -def test_resizetofill(): - img = ResizeToFill(100, 100).process(create_image()) - eq_(img.size, (100, 100)) - - -def test_resizetofit(): - # First create an image with aspect ratio 2:1... - img = Image.new('RGB', (200, 100)) - - # ...then resize it to fit within a 100x100 canvas. - img = ResizeToFit(100, 100).process(img) - - # Assert that the image has maintained the aspect ratio. - eq_(img.size, (100, 50)) - - -def test_resizetofit_mat(): - img = Image.new('RGB', (200, 100)) - img = ResizeToFit(100, 100, mat_color=0x000000).process(img) - eq_(img.size, (100, 100)) From 98552d7f7556348509ce67ba4fa19c26ac0fcdb2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 8 Feb 2013 18:08:29 -0500 Subject: [PATCH 219/527] Relax PILKit version requirement --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9a16e877..0affbae5 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ test_suite='testrunner.run_tests', install_requires=[ 'django-appconf>=0.5', - 'pilkit<2.0a0', + 'pilkit', ], classifiers=[ 'Development Status :: 5 - Production/Stable', From 969275bbc9a047b681c44a1fc4ad639c0171e346 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 8 Feb 2013 18:15:00 -0500 Subject: [PATCH 220/527] Rename GeneratedImageFile to ImageCacheFile --- docs/advanced_usage.rst | 4 ++-- imagekit/cachefiles/__init__.py | 12 ++++++------ imagekit/models/fields/utils.py | 4 ++-- imagekit/pkgmeta.py | 2 +- imagekit/registry.py | 4 ++-- imagekit/specs/sourcegroups.py | 4 ++-- imagekit/templatetags/imagekit.py | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 917b642c..ef6b125b 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -190,9 +190,9 @@ command. Luckily, ImageKit makes this pretty easy: .. code-block:: python - from imagekit.cachefiles import LazyGeneratedImageFile + from imagekit.cachefiles import LazyImageCacheFile - file = LazyGeneratedImageFile('myapp:profile:avatar_thumbnail', source=source_file) + file = LazyImageCacheFile('myapp:profile:avatar_thumbnail', source=source_file) file.generate() One final situation in which images won't be generated automatically when using diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 25c822f4..974b6439 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -7,7 +7,7 @@ from ..utils import get_logger, get_singleton, generate, get_by_qname -class GeneratedImageFile(BaseIKFile, ImageFile): +class ImageCacheFile(BaseIKFile, ImageFile): """ A file that represents the result of a generator. Creating an instance of this class is not enough to trigger the generation of the file. In fact, @@ -39,11 +39,11 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): self.cachefile_backend = cachefile_backend or getattr(generator, 'cachefile_backend', None) - super(GeneratedImageFile, self).__init__(storage=storage) + super(ImageCacheFile, self).__init__(storage=storage) def _require_file(self): before_access.send(sender=self, file=self) - return super(GeneratedImageFile, self)._require_file() + return super(ImageCacheFile, self)._require_file() def generate(self, force=False): if force: @@ -69,13 +69,13 @@ def _generate(self): self.cachefile_backend)) -class LazyGeneratedImageFile(LazyObject): +class LazyImageCacheFile(LazyObject): def __init__(self, generator_id, *args, **kwargs): - super(LazyGeneratedImageFile, self).__init__() + super(LazyImageCacheFile, self).__init__() def setup(): generator = generator_registry.get(generator_id, *args, **kwargs) - self._wrapped = GeneratedImageFile(generator) + self._wrapped = ImageCacheFile(generator) self.__dict__['_setup'] = setup diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index bfb6d894..ea2442f5 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,4 +1,4 @@ -from ...cachefiles import GeneratedImageFile +from ...cachefiles import ImageCacheFile from django.db.models.fields.files import ImageField @@ -30,7 +30,7 @@ def __get__(self, instance, owner): else: source = image_fields[0] spec = self.field.get_spec(source=source) - file = GeneratedImageFile(spec) + file = ImageCacheFile(spec) instance.__dict__[self.attname] = file return file diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 20e62db6..419d4088 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0a1' +__version__ = '3.0a2' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] diff --git a/imagekit/registry.py b/imagekit/registry.py index 2523f9b7..a28738f9 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -92,7 +92,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): Relay source group signals to the appropriate spec strategy. """ - from .cachefiles import GeneratedImageFile + from .cachefiles import ImageCacheFile source_group = sender # Ignore signals from unregistered groups. @@ -104,7 +104,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): callback_name = self._signals[signal] for spec in specs: - file = GeneratedImageFile(spec) + file = ImageCacheFile(spec) call_strategy_method(spec, callback_name, file=file) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index ec85af8a..16934704 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -13,7 +13,7 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps -from ..cachefiles import LazyGeneratedImageFile +from ..cachefiles import LazyImageCacheFile from ..signals import source_created, source_changed, source_deleted @@ -156,7 +156,7 @@ def __hash__(self): def __call__(self): for source_file in self.source_group.files(): - yield LazyGeneratedImageFile(self.generator_id, + yield LazyImageCacheFile(self.generator_id, source=source_file) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index c845dcca..7553a2f9 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -2,7 +2,7 @@ from django.utils.html import escape from django.utils.safestring import mark_safe from .compat import parse_bits -from ..cachefiles import GeneratedImageFile +from ..cachefiles import ImageCacheFile from ..registry import generator_registry @@ -18,7 +18,7 @@ def get_cachefile(context, generator_id, generator_kwargs, source=None): generator_id = generator_id.resolve(context) kwargs = dict((k, v.resolve(context)) for k, v in generator_kwargs.items()) generator = generator_registry.get(generator_id, **kwargs) - return GeneratedImageFile(generator) + return ImageCacheFile(generator) def parse_dimensions(dimensions): @@ -104,7 +104,7 @@ def render(self, context): kwargs.update(parse_dimensions(self._dimensions.resolve(context))) generator = generator_registry.get(generator_id, **kwargs) - context[variable_name] = GeneratedImageFile(generator) + context[variable_name] = ImageCacheFile(generator) return '' @@ -130,7 +130,7 @@ def render(self, context): kwargs.update(dimensions) generator = generator_registry.get(generator_id, **kwargs) - file = GeneratedImageFile(generator) + file = ImageCacheFile(generator) attrs = dict((k, v.resolve(context)) for k, v in self._html_attrs.items()) From af6ebcb469bf564be50a3f134eaa16e7be3e84b7 Mon Sep 17 00:00:00 2001 From: Sean Bell Date: Sat, 9 Feb 2013 00:55:49 -0500 Subject: [PATCH 221/527] Fixing iteration over objects for abstract models --- imagekit/specs/sourcegroups.py | 6 ++++-- imagekit/utils.py | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 16934704..b782595a 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -15,6 +15,7 @@ from django.utils.functional import wraps from ..cachefiles import LazyImageCacheFile from ..signals import source_created, source_changed, source_deleted +from ..utils import get_nonabstract_descendants def ik_model_receiver(fn): @@ -131,8 +132,9 @@ def files(self): particular model. """ - for instance in self.model_class.objects.all(): - yield getattr(instance, self.image_field) + for model in get_nonabstract_descendants(self.model_class): + for instance in model.objects.all().iterator(): + yield getattr(instance, self.image_field) class SourceGroupFilesGenerator(object): diff --git a/imagekit/utils.py b/imagekit/utils.py index 6f4fd525..d749ac63 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -23,6 +23,17 @@ def _get_models(apps): return models +def get_nonabstract_descendants(model): + """ Returns all non-abstract descendants of the model. """ + if model._meta.abstract: + descendants = [] + for m in model.__subclasses__(): + descendants += get_nonabstract_descendants(m) + return descendants + else: + return [model] + + def get_by_qname(path, desc): try: dot = path.rindex('.') From df41459e65d088210a038f5eccb130b625614bc3 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 15:39:33 -0500 Subject: [PATCH 222/527] Fix signals for abstract models Includes a fix for undispatched signals, as well as signals being handled twice. A regression of #126 Related: #185 --- imagekit/specs/sourcegroups.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index b782595a..59810bd7 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -13,6 +13,7 @@ from django.db.models.signals import post_init, post_save, post_delete from django.utils.functional import wraps +import inspect from ..cachefiles import LazyImageCacheFile from ..signals import source_created, source_changed, source_deleted from ..utils import get_nonabstract_descendants @@ -26,8 +27,15 @@ def ik_model_receiver(fn): """ @wraps(fn) def receiver(self, sender, **kwargs): - if sender in (src.model_class for src in self._source_groups): - fn(self, sender=sender, **kwargs) + if not inspect.isclass(sender): + return + for src in self._source_groups: + if issubclass(sender, src.model_class): + fn(self, sender=sender, **kwargs) + + # If we find a match, return. We don't want to handle the signal + # more than once. + return return receiver @@ -77,7 +85,7 @@ def get_field_dict(self, instance): """ return dict((src.image_field, getattr(instance, src.image_field)) for - src in self._source_groups if src.model_class is instance.__class__) + src in self._source_groups if isinstance(instance, src.model_class)) @ik_model_receiver def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): @@ -110,7 +118,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): """ for source_group in self._source_groups: - if source_group.model_class is model_class and source_group.image_field == attname: + if issubclass(model_class, source_group.model_class) and source_group.image_field == attname: signal.send(sender=source_group, source=file) From de550b71df79ff6883157dfd24e0b640dbd03507 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 15:41:24 -0500 Subject: [PATCH 223/527] Add test for abstract model signals --- tests/models.py | 28 +++++++++++++++++++++------- tests/test_abstract_models.py | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 tests/test_abstract_models.py diff --git a/tests/models.py b/tests/models.py index 17e887be..61265f0a 100644 --- a/tests/models.py +++ b/tests/models.py @@ -26,17 +26,31 @@ class ProcessedImageFieldModel(models.Model): options={'quality': 90}, upload_to='p') +class CountingCacheFileStrategy(object): + def __init__(self): + self.before_access_count = 0 + self.on_source_changed_count = 0 + self.on_source_created_count = 0 + + def before_access(self, file): + self.before_access_count += 1 + + def on_source_changed(self, file): + self.on_source_changed_count += 1 + + def on_source_created(self, file): + self.on_source_created_count += 1 + + class AbstractImageModel(models.Model): original_image = models.ImageField(upload_to='photos') - abstract_class_spec = ImageSpecField() + abstract_class_spec = ImageSpecField(source='original_image', + format='JPEG', + cachefile_strategy=CountingCacheFileStrategy()) class Meta: abstract = True -class ConcreteImageModel1(AbstractImageModel): - first_spec = ImageSpecField() - - -class ConcreteImageModel2(AbstractImageModel): - second_spec = ImageSpecField() +class ConcreteImageModel(AbstractImageModel): + pass diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py new file mode 100644 index 00000000..c1441361 --- /dev/null +++ b/tests/test_abstract_models.py @@ -0,0 +1,22 @@ +from django.core.files import File +from imagekit.signals import source_created +from imagekit.specs.sourcegroups import ImageFieldSourceGroup +from nose.tools import eq_ +from . models import AbstractImageModel, ConcreteImageModel +from .utils import get_image_file + + +def test_source_created_signal(): + source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') + count = [0] + + def receiver(sender, *args, **kwargs): + if sender is source_group: + count[0] += 1 + + source_created.connect(receiver, dispatch_uid='test_source_created') + instance = ConcreteImageModel() + img = File(get_image_file()) + instance.original_image.save('test_source_created_signal.jpg', img) + + eq_(count[0], 1) From 7bf3e4e7a3f99b405c4f653b8a16ff0b18ebcb01 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 15:54:17 -0500 Subject: [PATCH 224/527] Add test for @seanbell's utility Currently failing --- tests/models.py | 4 ++++ tests/test_abstract_models.py | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/models.py b/tests/models.py index 61265f0a..7520a5cf 100644 --- a/tests/models.py +++ b/tests/models.py @@ -54,3 +54,7 @@ class Meta: class ConcreteImageModel(AbstractImageModel): pass + + +class ConcreteImageModelSubclass(ConcreteImageModel): + pass diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py index c1441361..a3ec7749 100644 --- a/tests/test_abstract_models.py +++ b/tests/test_abstract_models.py @@ -1,8 +1,10 @@ from django.core.files import File from imagekit.signals import source_created from imagekit.specs.sourcegroups import ImageFieldSourceGroup +from imagekit.utils import get_nonabstract_descendants from nose.tools import eq_ -from . models import AbstractImageModel, ConcreteImageModel +from . models import (AbstractImageModel, ConcreteImageModel, + ConcreteImageModelSubclass) from .utils import get_image_file @@ -20,3 +22,8 @@ def receiver(sender, *args, **kwargs): instance.original_image.save('test_source_created_signal.jpg', img) eq_(count[0], 1) + + +def test_nonabstract_descendants_generator(): + descendants = list(get_nonabstract_descendants(AbstractImageModel)) + eq_(descendants, [ConcreteImageModel, ConcreteImageModelSubclass]) From 90ae9e83391b2a8b3d66384ba3b376c6a1f66257 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 15:55:32 -0500 Subject: [PATCH 225/527] Fix get_nonabstract_descendants Previously, function was only returning the first non-abstract descendant. (It should also return concrete descendants of concrete descendants, which it now does.) Also, converted to generator. --- imagekit/utils.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index d749ac63..91f33446 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -25,13 +25,11 @@ def _get_models(apps): def get_nonabstract_descendants(model): """ Returns all non-abstract descendants of the model. """ - if model._meta.abstract: - descendants = [] - for m in model.__subclasses__(): - descendants += get_nonabstract_descendants(m) - return descendants - else: - return [model] + if not model._meta.abstract: + yield model + for s in model.__subclasses__(): + for m in get_nonabstract_descendants(s): + yield m def get_by_qname(path, desc): From b53b7c3cae56e30f74c3cf0a67fb9dd658711d35 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 16:01:50 -0500 Subject: [PATCH 226/527] Clarify ImageFieldSourceGroup docstrings --- imagekit/specs/sourcegroups.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 59810bd7..69f2daf6 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -125,7 +125,7 @@ def dispatch_signal(self, signal, file, model_class, instance, attname): class ImageFieldSourceGroup(object): """ A source group that repesents a particular field across all instances of a - model. + model and its subclasses. """ def __init__(self, model_class, image_field): @@ -137,7 +137,7 @@ def files(self): """ A generator that returns the source files that this source group represents; in this case, a particular field of every instance of a - particular model. + particular model and its subclasses. """ for model in get_nonabstract_descendants(self.model_class): From 5c944c5efb4a31dddd90dc4b242705dc97970ad3 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 10 Feb 2013 16:05:21 -0500 Subject: [PATCH 227/527] Bump version to 3.0a3 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 419d4088..91d39aad 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0a2' +__version__ = '3.0a3' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 896e289884efb297abcac32500120322da333fe5 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 12 Feb 2013 20:46:35 -0500 Subject: [PATCH 228/527] Add @seanbell to AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index d91cb936..51784081 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,6 +26,7 @@ Contributors * `Jan Sagemüller`_ * `Clay McClure`_ * `Jannis Leidel`_ +* `Sean Bell`_ .. _Justin Driscoll: http://github.com/jdriscoll .. _HZDG: http://hzdg.com @@ -45,3 +46,4 @@ Contributors .. _Jan Sagemüller: https://github.com/version2 .. _Clay McClure: https://github.com/claymation .. _Jannis Leidel: https://github.com/jezdez +.. _Sean Bell: https://github.com/seanbell From e456e0fd99d8556a4d6e818f20f8ce7b83d140f2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 12 Feb 2013 19:41:07 -0500 Subject: [PATCH 229/527] Remove util tests These are part of PILKit --- tests/test_utils.py | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 tests/test_utils.py diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index f4c777ec..00000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,23 +0,0 @@ -from imagekit.exceptions import UnknownFormatError, UnknownExtensionError -from imagekit.utils import extension_to_format, format_to_extension -from nose.tools import eq_, raises - - -def test_extension_to_format(): - eq_(extension_to_format('.jpeg'), 'JPEG') - eq_(extension_to_format('.rgba'), 'SGI') - - -def test_format_to_extension_no_init(): - eq_(format_to_extension('PNG'), '.png') - eq_(format_to_extension('ICO'), '.ico') - - -@raises(UnknownFormatError) -def test_unknown_format(): - format_to_extension('TXT') - - -@raises(UnknownExtensionError) -def test_unknown_extension(): - extension_to_format('.txt') From f5a078b68fb325a0a01b31f0c74cd76e95791708 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 12 Feb 2013 19:43:57 -0500 Subject: [PATCH 230/527] Remove old util --- imagekit/utils.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 91f33446..b0857703 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -8,13 +8,6 @@ from pilkit.utils import * -def get_spec_files(instance): - try: - return instance._ik.spec_files - except AttributeError: - return [] - - def _get_models(apps): models = [] for app_label in apps or []: From dff01823103243a7fb1b3fe7000537a89bfb9e3a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 12 Feb 2013 19:45:31 -0500 Subject: [PATCH 231/527] Remove another old util --- imagekit/utils.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index b0857703..ae81760e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -3,19 +3,10 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files import File -from django.db.models.loading import cache from django.utils.importlib import import_module from pilkit.utils import * -def _get_models(apps): - models = [] - for app_label in apps or []: - app = cache.get_app(app_label) - models += [m for m in cache.get_models(app)] - return models - - def get_nonabstract_descendants(model): """ Returns all non-abstract descendants of the model. """ if not model._meta.abstract: From 74ae51f1640dcc38fa5410f14d9f19938e0c4982 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 21:56:51 -0500 Subject: [PATCH 232/527] Add venv and .env to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7380ca53..40b09c6a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ build dist /tests/media/* !/tests/media/lenna.png +/venv +/.env From 190153d06864b64275fbd515c2f1a2b8c8a5cdba Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 22:15:57 -0500 Subject: [PATCH 233/527] Add test to ensure sourceless specs are falsy Currently failing; related to #187 --- tests/test_specs.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/test_specs.py diff --git a/tests/test_specs.py b/tests/test_specs.py new file mode 100644 index 00000000..6c8c4b94 --- /dev/null +++ b/tests/test_specs.py @@ -0,0 +1,12 @@ +from imagekit.cachefiles import ImageCacheFile +from nose.tools import assert_false +from .imagegenerators import TestSpec + + +def test_no_source(): + """ + Ensure sourceless specs are falsy. + """ + spec = TestSpec(source=None) + file = ImageCacheFile(spec) + assert_false(bool(file)) From b33869a9f8d25c7c4d5a720c120309bae1fa71c0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 22:18:33 -0500 Subject: [PATCH 234/527] Sourceless specs are falsy Passes test added in 190153d. Related to #187 --- imagekit/cachefiles/__init__.py | 8 +++++--- imagekit/specs/__init__.py | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 974b6439..e606e18a 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -27,10 +27,12 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): """ self.generator = generator - name = name or getattr(generator, 'cachefile_name', None) if not name: - fn = get_by_qname(settings.IMAGEKIT_CACHEFILE_NAMER, 'namer') - name = fn(generator) + try: + name = generator.cachefile_name + except AttributeError: + fn = get_by_qname(settings.IMAGEKIT_CACHEFILE_NAMER, 'namer') + name = fn(generator) self.name = name storage = storage or getattr(generator, 'cachefile_storage', diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 969dcf37..a8fa742f 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -82,6 +82,8 @@ def __init__(self, source): @property def cachefile_name(self): + if not self.source: + return None fn = get_by_qname(settings.IMAGEKIT_SPEC_CACHEFILE_NAMER, 'namer') return fn(self) From 61aa1c32e7f9b45d247347eca7e88baca873b0f8 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 22:22:27 -0500 Subject: [PATCH 235/527] Bump version to 3.0a4 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 91d39aad..bda76813 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0a3' +__version__ = '3.0a4' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 92a3c2688cfa2a63687228765342422cd3ee362a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 22:34:24 -0500 Subject: [PATCH 236/527] Error when attempting to generate image w/o source --- imagekit/exceptions.py | 4 ++++ imagekit/specs/__init__.py | 12 ++++++++++++ tests/test_specs.py | 9 ++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index 0c46514e..9aba0181 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -13,6 +13,10 @@ class MissingGeneratorId(Exception): pass +class MissingSource(ValueError): + pass + + # Aliases for backwards compatibility UnknownExtensionError = UnknownExtension UnknownFormatError = UnknownFormat diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index a8fa742f..c12acfad 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,6 +4,7 @@ import pickle from ..cachefiles.backends import get_default_cachefile_backend from ..cachefiles.strategies import StrategyWrapper +from ..exceptions import MissingSource from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, get_by_qname from ..registry import generator_registry, register @@ -41,6 +42,13 @@ def __init__(self): def generate(self): raise NotImplementedError + MissingSource = MissingSource + """ + Raised when an operation requiring a source is attempted on a spec that has + no source. + + """ + class ImageSpec(BaseImageSpec): """ @@ -116,6 +124,10 @@ def get_hash(self): ])).hexdigest() def generate(self): + if not self.source: + raise MissingSource("The spec '%s' has no source file associated" + " with it." % self) + # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) img = open_image(self.source) diff --git a/tests/test_specs.py b/tests/test_specs.py index 6c8c4b94..5db081f2 100644 --- a/tests/test_specs.py +++ b/tests/test_specs.py @@ -1,5 +1,5 @@ from imagekit.cachefiles import ImageCacheFile -from nose.tools import assert_false +from nose.tools import assert_false, raises from .imagegenerators import TestSpec @@ -10,3 +10,10 @@ def test_no_source(): spec = TestSpec(source=None) file = ImageCacheFile(spec) assert_false(bool(file)) + + +@raises(TestSpec.MissingSource) +def test_no_source_error(): + spec = TestSpec(source=None) + file = ImageCacheFile(spec) + file.generate() From c64eee40b32a025e97898bd33ff1d5bca351d65b Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 25 Feb 2013 22:43:37 -0500 Subject: [PATCH 237/527] Bump version to 3.0a5 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index bda76813..a3b1dc3b 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0a4' +__version__ = '3.0a5' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 14be033b7fc8cca80738a6356576a24a849bf266 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 13 Mar 2013 23:41:28 -0400 Subject: [PATCH 238/527] Add SECRET_KEY for tests --- tests/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/settings.py b/tests/settings.py index 3272aee0..01b93a23 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -21,6 +21,8 @@ }, } +SECRET_KEY = '_uobce43e5osp8xgzle*yag2_16%y$sf*5(12vfg25hpnxik_*' + INSTALLED_APPS = [ 'django.contrib.auth', 'django.contrib.contenttypes', From d62d8a824e00444e09e8e2f8199278265cba4188 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 22:08:34 -0400 Subject: [PATCH 239/527] Rename test_specs --- tests/{test_specs.py => test_cachefiles.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{test_specs.py => test_cachefiles.py} (100%) diff --git a/tests/test_specs.py b/tests/test_cachefiles.py similarity index 100% rename from tests/test_specs.py rename to tests/test_cachefiles.py From aae6aeb142e92305c71ec392c6bf35d7d60a0317 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 22:23:47 -0400 Subject: [PATCH 240/527] Add truthy/falsy file assertion utils --- tests/test_cachefiles.py | 5 +++-- tests/utils.py | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 5db081f2..6579e891 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,6 +1,7 @@ from imagekit.cachefiles import ImageCacheFile -from nose.tools import assert_false, raises +from nose.tools import raises from .imagegenerators import TestSpec +from .utils import assert_file_is_falsy def test_no_source(): @@ -9,7 +10,7 @@ def test_no_source(): """ spec = TestSpec(source=None) file = ImageCacheFile(spec) - assert_false(bool(file)) + assert_file_is_falsy(file) @raises(TestSpec.MissingSource) diff --git a/tests/utils.py b/tests/utils.py index 2763f8ff..39f22713 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,6 +4,7 @@ from django.core.files import File from django.template import Context, Template from imagekit.lib import Image, StringIO +from nose.tools import assert_true, assert_false import pickle from .models import Photo @@ -53,3 +54,11 @@ def render_tag(ttag): def get_html_attrs(ttag): return BeautifulSoup(render_tag(ttag)).img.attrs + + +def assert_file_is_falsy(file): + assert_false(bool(file), 'File is not falsy') + + +def assert_file_is_truthy(file): + assert_true(bool(file), 'File is not truthy') From 044a3625f91b209b71862a564b0d6b6b2afe548e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 22:55:40 -0400 Subject: [PATCH 241/527] Correct error message --- imagekit/cachefiles/__init__.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index e606e18a..d490773c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -60,15 +60,18 @@ def _generate(self): actual_name = self.storage.save(self.name, content) if actual_name != self.name: - get_logger().warning('The storage backend %s did not save the file' - ' with the requested name ("%s") and instead used' - ' "%s". This may be because a file already existed with' - ' the requested name. If so, you may have meant to call' - ' ensure_exists() instead of generate(), or there may be a' - ' race condition in the file backend %s. The saved file' - ' will not be used.' % (self.storage, + get_logger().warning( + 'The storage backend %s did not save the file with the' + ' requested name ("%s") and instead used "%s". This may be' + ' because a file already existed with the requested name. If' + ' so, you may have meant to call generate() instead of' + ' generate(force=True), or there may be a race condition in the' + ' file backend %s. The saved file will not be used.' % ( + self.storage, self.name, actual_name, - self.cachefile_backend)) + self.cachefile_backend + ) + ) class LazyImageCacheFile(LazyObject): From f181d300084695d5a9a66f9d89ad26d3a798aa83 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 22:58:28 -0400 Subject: [PATCH 242/527] Rename file_exists to exists --- imagekit/cachefiles/backends.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 15813be4..b43232c9 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -29,16 +29,16 @@ def get_key(self, file): from django.conf import settings return '%s%s-exists' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) - def file_exists(self, file): + def exists(self, file): key = self.get_key(file) exists = self.cache.get(key) if exists is None: - exists = self._file_exists(file) + exists = self._exists(file) self.cache.set(key, exists) return exists def ensure_exists(self, file): - if self.file_exists(file): + if self.exists(file): self.create(file) self.cache.set(self.get_key(file), True) @@ -50,7 +50,7 @@ class Simple(CachedFileBackend): """ - def _file_exists(self, file): + def _exists(self, file): if not getattr(file, '_file', None): # No file on object. Have to check storage. return not file.storage.exists(file.name) From ac92b777096ffcfffcaf4948ce724433ea0d6681 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 23:04:30 -0400 Subject: [PATCH 243/527] Fix loopy existence check Sometimes two wrongs do make a right I guess. But better to have two rights. --- imagekit/cachefiles/backends.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index b43232c9..e09cce8c 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -38,7 +38,7 @@ def exists(self, file): return exists def ensure_exists(self, file): - if self.exists(file): + if not self.exists(file): self.create(file) self.cache.set(self.get_key(file), True) @@ -51,10 +51,7 @@ class Simple(CachedFileBackend): """ def _exists(self, file): - if not getattr(file, '_file', None): - # No file on object. Have to check storage. - return not file.storage.exists(file.name) - return False + return getattr(file, '_file', None) or file.storage.exists(file.name) def create(self, file): """ From 54dda25adba9121b020b9c81cda3c1d7d5912862 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 23:34:27 -0400 Subject: [PATCH 244/527] Generation goes through backend; use states We might as well account for asynchronous generation in our CachedFileBackend. --- imagekit/cachefiles/__init__.py | 10 ++++--- imagekit/cachefiles/backends.py | 49 +++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index d490773c..24a77e3d 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -48,10 +48,12 @@ def _require_file(self): return super(ImageCacheFile, self)._require_file() def generate(self, force=False): - if force: - self._generate() - else: - self.cachefile_backend.ensure_exists(self) + """ + Generate the file. If ``force`` is ``True``, the file will be generated + immediately, whether the file already exists or not. + + """ + self.cachefile_backend.generate(self, force) def _generate(self): # Generate the file diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index e09cce8c..0a9ff489 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -3,6 +3,12 @@ from django.core.exceptions import ImproperlyConfigured +class CacheFileState(object): + EXISTS = 'exists' + PENDING = 'pending' + DOES_NOT_EXIST = 'does_not_exist' + + def get_default_cachefile_backend(): """ Get the default file backend. @@ -27,35 +33,42 @@ def cache(self): def get_key(self, file): from django.conf import settings - return '%s%s-exists' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) + return '%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) - def exists(self, file): + def get_state(self, file): key = self.get_key(file) - exists = self.cache.get(key) - if exists is None: + state = self.cache.get(key) + if state is None: exists = self._exists(file) - self.cache.set(key, exists) - return exists + state = CacheFileState.EXISTS if exists else CacheFileState.DOES_NOT_EXIST + self.set_state(file, state) + return state + + def set_state(self, file, state): + key = self.get_key(file) + self.cache.set(key, state) - def ensure_exists(self, file): - if not self.exists(file): - self.create(file) - self.cache.set(self.get_key(file), True) + def exists(self, file): + return self.get_state(file) is CacheFileState.EXISTS + + def generate(self, file, force=False): + if force: + file._generate() + elif self.get_state(file) is CacheFileState.DOES_NOT_EXIST: + # Don't generate if the file exists or is pending. + self._generate(file) class Simple(CachedFileBackend): """ The most basic file backend. The storage is consulted to see if the file - exists. + exists. Files are generated synchronously. """ + def _generate(self, file): + file._generate() + self.set_state(file, CacheFileState.EXISTS) + def _exists(self, file): return getattr(file, '_file', None) or file.storage.exists(file.name) - - def create(self, file): - """ - Generates a new image by running the processors on the source file. - - """ - file.generate(force=True) From fc87c0497cfa5c775163e3f170079ebc8dee1205 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 14 Mar 2013 23:36:21 -0400 Subject: [PATCH 245/527] Add abstract cachefile backend for illustration --- imagekit/cachefiles/backends.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 0a9ff489..62b59ba6 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -23,6 +23,20 @@ class InvalidFileBackendError(ImproperlyConfigured): pass +class AbstractCacheFileBackend(object): + """ + An abstract cache file backend. This isn't used by any internal classes and + is included simply to illustrate the minimum interface of a cache file + backend for users who wish to implement their own. + + """ + def generate(self, file, force=False): + raise NotImplementedError + + def exists(self, file): + raise NotImplementedError + + class CachedFileBackend(object): @property def cache(self): From c48c720f8a7cfda47c46b38004d80921ab2ea305 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 00:27:23 -0400 Subject: [PATCH 246/527] Add __nonzero__ method that will work for async --- imagekit/cachefiles/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 24a77e3d..c53a5ef6 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -75,6 +75,15 @@ def _generate(self): ) ) + def __nonzero__(self): + if not self.name: + return False + + # Dispatch the before_access signal before checking to see if the file + # exists. This gives the strategy a chance to create the file. + before_access.send(sender=self, file=self) + return self.cachefile_backend.exists(self) + class LazyImageCacheFile(LazyObject): def __init__(self, generator_id, *args, **kwargs): From 70ff6dc788666c93bcfa38268906f60efd0e2646 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 00:30:58 -0400 Subject: [PATCH 247/527] Store state when force-generated --- imagekit/cachefiles/backends.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 62b59ba6..51d594c8 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -68,6 +68,7 @@ def exists(self, file): def generate(self, file, force=False): if force: file._generate() + self.set_state(file, CacheFileState.EXISTS) elif self.get_state(file) is CacheFileState.DOES_NOT_EXIST: # Don't generate if the file exists or is pending. self._generate(file) From 1e129c5b700fb7a366d640dbdcb2f2c838661ec0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 00:49:24 -0400 Subject: [PATCH 248/527] Convert to boolean --- imagekit/cachefiles/backends.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 51d594c8..70edc936 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -86,4 +86,5 @@ def _generate(self, file): self.set_state(file, CacheFileState.EXISTS) def _exists(self, file): - return getattr(file, '_file', None) or file.storage.exists(file.name) + return bool(getattr(file, '_file', None) + or file.storage.exists(file.name)) From b061e135c27e423ab098b2e7a6e9137ca67cf718 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 00:49:44 -0400 Subject: [PATCH 249/527] Add tests for cachefile truthiness --- tests/test_cachefiles.py | 29 ++++++++++++++++++++++++++--- tests/utils.py | 18 ++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 6579e891..d3c29028 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,18 +1,41 @@ from imagekit.cachefiles import ImageCacheFile from nose.tools import raises from .imagegenerators import TestSpec -from .utils import assert_file_is_falsy +from .utils import (assert_file_is_truthy, assert_file_is_falsy, + DummyAsyncCacheFileBackend, get_unique_image_file) -def test_no_source(): +def test_no_source_falsiness(): """ - Ensure sourceless specs are falsy. + Ensure cache files generated from sourceless specs are falsy. + """ spec = TestSpec(source=None) file = ImageCacheFile(spec) assert_file_is_falsy(file) +def test_sync_backend_truthiness(): + """ + Ensure that a cachefile with a synchronous cache file backend (the default) + is truthy. + + """ + spec = TestSpec(source=get_unique_image_file()) + file = ImageCacheFile(spec) + assert_file_is_truthy(file) + + +def test_async_backend_falsiness(): + """ + Ensure that a cachefile with an asynchronous cache file backend is falsy. + + """ + spec = TestSpec(source=get_unique_image_file()) + file = ImageCacheFile(spec, cachefile_backend=DummyAsyncCacheFileBackend()) + assert_file_is_falsy(file) + + @raises(TestSpec.MissingSource) def test_no_source_error(): spec = TestSpec(source=None) diff --git a/tests/utils.py b/tests/utils.py index 39f22713..07085dfb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -3,9 +3,11 @@ from django.conf import settings from django.core.files import File from django.template import Context, Template +from imagekit.cachefiles.backends import Simple, CacheFileState from imagekit.lib import Image, StringIO from nose.tools import assert_true, assert_false import pickle +from tempfile import NamedTemporaryFile from .models import Photo @@ -21,6 +23,12 @@ def get_image_file(): return open(path, 'r+b') +def get_unique_image_file(): + file = NamedTemporaryFile() + file.write(get_image_file().read()) + return file + + def create_image(): return Image.open(get_image_file()) @@ -62,3 +70,13 @@ def assert_file_is_falsy(file): def assert_file_is_truthy(file): assert_true(bool(file), 'File is not truthy') + + +class DummyAsyncCacheFileBackend(Simple): + """ + A cache file backend meant to simulate async generation (by marking the + file as pending but never actually creating it). + + """ + def _generate(self, file): + self.set_state(file, CacheFileState.PENDING) From 3d6a9de9aaaa8254a82388ebdf250502285dc082 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 01:05:53 -0400 Subject: [PATCH 250/527] Add existence check timeout --- imagekit/cachefiles/backends.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 70edc936..1c239da6 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -38,6 +38,16 @@ def exists(self, file): class CachedFileBackend(object): + existence_check_timeout = 5 + """ + The number of seconds to wait before rechecking to see if the file exists. + If the image is found to exist, that information will be cached using the + timeout specified in your CACHES setting (which should be very high). + However, when the file does not exist, you probably want to check again + in a relatively short amount of time. This attribute allows you to do that. + + """ + @property def cache(self): if not getattr(self, '_cache', None): @@ -60,7 +70,10 @@ def get_state(self, file): def set_state(self, file, state): key = self.get_key(file) - self.cache.set(key, state) + if state is CacheFileState.DOES_NOT_EXIST: + self.cache.set(key, state, self.existence_check_timeout) + else: + self.cache.set(key, state) def exists(self, file): return self.get_state(file) is CacheFileState.EXISTS From 86cd23e906d6bbb12eefa87d8f8c051be0530121 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 15 Mar 2013 01:06:28 -0400 Subject: [PATCH 251/527] Remove actions module --- imagekit/cachefiles/actions.py | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 imagekit/cachefiles/actions.py diff --git a/imagekit/cachefiles/actions.py b/imagekit/cachefiles/actions.py deleted file mode 100644 index 634bcbe1..00000000 --- a/imagekit/cachefiles/actions.py +++ /dev/null @@ -1,22 +0,0 @@ -def generate(file): - file.generate() - - -try: - from celery.task import task -except ImportError: - pass -else: - generate_task = task(generate) - - -def generate_deferred(file): - try: - import celery # NOQA - except: - raise ImportError("Deferred validation requires the the 'celery' library") - generate_task.delay(file) - - -def clear_now(file): - file.clear() From 728368abf66f88307263c2ff3edafc28c41aeb16 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 22:29:53 -0400 Subject: [PATCH 252/527] Add async cachefile backend --- imagekit/cachefiles/__init__.py | 1 - imagekit/cachefiles/backends.py | 31 +++++++++++++++++++++++++++++++ setup.py | 3 +++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index c53a5ef6..c3b50b0c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -45,7 +45,6 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): def _require_file(self): before_access.send(sender=self, file=self) - return super(ImageCacheFile, self)._require_file() def generate(self, force=False): """ diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 1c239da6..50c42f49 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -101,3 +101,34 @@ def _generate(self, file): def _exists(self, file): return bool(getattr(file, '_file', None) or file.storage.exists(file.name)) + + +def _generate_file(backend, file): + file._generate() + backend.set_state(file, CacheFileState.EXISTS) + + +try: + import celery +except ImportError: + pass +else: + _generate_file = celery.task(ignore_result=True)(_generate_file) + + +class Async(Simple): + """ + A backend that uses Celery to generate the images. + """ + + def __init__(self, *args, **kwargs): + try: + import celery + except ImportError: + raise ImproperlyConfigured('You must install celery to use' + ' imagekit.cachefiles.backend.Async.') + super(Async, self).__init__(*args, **kwargs) + + def _generate(self, file): + self.set_state(file, CacheFileState.PENDING) + _generate_file.delay(self, file) diff --git a/setup.py b/setup.py index 0affbae5..2dc131f7 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,9 @@ 'django-appconf>=0.5', 'pilkit', ], + extras_require={ + 'async': ['django-celery>=3.0'], + }, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', From 3ca8c53698447437c4a69617a15397b2419838ac Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 22:37:52 -0400 Subject: [PATCH 253/527] Also defer existance check --- imagekit/cachefiles/backends.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 50c42f49..02d60faa 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -80,11 +80,14 @@ def exists(self, file): def generate(self, file, force=False): if force: + self.generate_now(file, force) + else: + self._generate(file) + + def generate_now(self, file, force=False): + if force or self.get_state(file) is CacheFileState.DOES_NOT_EXIST: file._generate() self.set_state(file, CacheFileState.EXISTS) - elif self.get_state(file) is CacheFileState.DOES_NOT_EXIST: - # Don't generate if the file exists or is pending. - self._generate(file) class Simple(CachedFileBackend): @@ -95,8 +98,7 @@ class Simple(CachedFileBackend): """ def _generate(self, file): - file._generate() - self.set_state(file, CacheFileState.EXISTS) + self.generate_now(file) def _exists(self, file): return bool(getattr(file, '_file', None) @@ -104,8 +106,7 @@ def _exists(self, file): def _generate_file(backend, file): - file._generate() - backend.set_state(file, CacheFileState.EXISTS) + backend.generate_now(file) try: From 2b10e85813ab8924ff1d992475951596165bc067 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 22:55:44 -0400 Subject: [PATCH 254/527] Clarify "force" kwarg --- imagekit/cachefiles/__init__.py | 2 +- imagekit/cachefiles/backends.py | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index c3b50b0c..c60d8a93 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -49,7 +49,7 @@ def _require_file(self): def generate(self, force=False): """ Generate the file. If ``force`` is ``True``, the file will be generated - immediately, whether the file already exists or not. + whether the file already exists or not. """ self.cachefile_backend.generate(self, force) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 02d60faa..5a57c204 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -79,10 +79,7 @@ def exists(self, file): return self.get_state(file) is CacheFileState.EXISTS def generate(self, file, force=False): - if force: - self.generate_now(file, force) - else: - self._generate(file) + raise NotImplementedError def generate_now(self, file, force=False): if force or self.get_state(file) is CacheFileState.DOES_NOT_EXIST: @@ -97,16 +94,16 @@ class Simple(CachedFileBackend): """ - def _generate(self, file): - self.generate_now(file) + def generate(self, file, force=False): + self.generate_now(file, force=force) def _exists(self, file): return bool(getattr(file, '_file', None) or file.storage.exists(file.name)) -def _generate_file(backend, file): - backend.generate_now(file) +def _generate_file(backend, file, force=False): + backend.generate_now(file, force=force) try: @@ -130,6 +127,6 @@ def __init__(self, *args, **kwargs): ' imagekit.cachefiles.backend.Async.') super(Async, self).__init__(*args, **kwargs) - def _generate(self, file): + def generate(self, file, force=False): self.set_state(file, CacheFileState.PENDING) - _generate_file.delay(self, file) + _generate_file.delay(self, file, force=force) From fbf052ce5fcaf78e4a29eea8eec6a3e930da746f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 23:00:54 -0400 Subject: [PATCH 255/527] Fix test: update DummyAsyncCacheFileBackend API --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 07085dfb..717442a3 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -78,5 +78,5 @@ class DummyAsyncCacheFileBackend(Simple): file as pending but never actually creating it). """ - def _generate(self, file): + def generate(self, file, force=False): self.set_state(file, CacheFileState.PENDING) From 28ffd444d6d7bbb68b39dc4e318b56f4dd9c8b15 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 23:01:38 -0400 Subject: [PATCH 256/527] Relax Pillow testing requirement --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2dc131f7..7ed1473e 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ 'nose==1.2.1', 'nose-progressive==1.3', 'django-nose==1.1', - 'Pillow==1.7.8', + 'Pillow<3.0', ], test_suite='testrunner.run_tests', install_requires=[ From c0ce3b5209a5aa0d38462873248bb6869900f5ad Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 2 Apr 2013 23:31:15 -0400 Subject: [PATCH 257/527] Add "Deferred Generation" section to docs --- docs/advanced_usage.rst | 46 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index ef6b125b..e7d35cb4 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -115,10 +115,13 @@ Optimizing Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't persist any data in the database. Therefore, in order to know whether an image file needs to be generated, ImageKit needs to check if the file already exists -(using the appropriate file storage object`__). The object responsible for +(using the appropriate `file storage object`__). The object responsible for performing these checks is called a *cache file backend*. +__ https://docs.djangoproject.com/en/dev/topics/files/#file-storage + + Cache! ------ @@ -142,6 +145,47 @@ set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, timeout. +Deferring Image Generation +-------------------------- + +As mentioned above, image generation is normally done synchronously. However, +you can also take advantage of deferred generation. In order to do this, you'll +need to do two things: 1) install `django-celery`__ and 2) tell ImageKit to use +the async cachefile backend. You can do this either on a per-spec basis (by +setting the ``cachefile_backend`` attribute), or for your project by setting +``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` in your settings.py: + +.. code-block:: python + + IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Async' + +Images will now be generated asynchronously. But watch out! Asynchrounous +generation means you'll have to account for images that haven't been generated +yet. You can do this by checking the truthiness of your files; if an image +hasn't been generated, it will be falsy: + +.. code-block:: html + + {% if not profile.avatar_thumbnail %} + + {% else %} + + {% endif %} + +Or, in Python: + +.. code-block:: python + + profile = Profile.objects.all()[0] + if profile.avatar_thumbnail: + url = profile.avatar_thumbnail.url + else: + url = '/path/to/placeholder.jpg' + + +__ https://pypi.python.org/pypi/django-celery + + Even More Advanced ------------------ From 681527fa9da3ae8e29668fe30b4889f2d6134e07 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 3 Apr 2013 00:21:04 -0400 Subject: [PATCH 258/527] Remove implicit source logic from descriptor This needs to be known earlier, when registering the source group, so we do it in `contribute_to_class` instead. Closes #188. --- imagekit/models/fields/__init__.py | 22 +++++++++++++++++++--- imagekit/models/fields/utils.py | 23 +++-------------------- tests/models.py | 5 +++-- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 292f410b..1042d834 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -41,12 +41,28 @@ def __init__(self, processors=None, format=None, options=None, self.source = source def contribute_to_class(self, cls, name): - setattr(cls, name, ImageSpecFileDescriptor(self, name)) + # If the source field name isn't defined, figure it out. + source = self.source + if not source: + image_fields = [f.attname for f in cls._meta.fields if + isinstance(f, models.ImageField)] + if len(image_fields) == 0: + raise Exception( + '%s does not define any ImageFields, so your %s' + ' ImageSpecField has no image to act on.' % + (cls.__name__, name)) + elif len(image_fields) > 1: + raise Exception( + '%s defines multiple ImageFields, but you have not' + ' specified a source for your %s ImageSpecField.' % + (cls.__name__, name)) + source = image_fields[0] + + setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) self.set_spec_id(cls, name) # Add the model and field as a source for this spec id - register.source_group(self.spec_id, - ImageFieldSourceGroup(cls, self.source)) + register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) class ProcessedImageField(models.ImageField, SpecHostField): diff --git a/imagekit/models/fields/utils.py b/imagekit/models/fields/utils.py index ea2442f5..6cd74a07 100644 --- a/imagekit/models/fields/utils.py +++ b/imagekit/models/fields/utils.py @@ -1,34 +1,17 @@ from ...cachefiles import ImageCacheFile -from django.db.models.fields.files import ImageField class ImageSpecFileDescriptor(object): - def __init__(self, field, attname): + def __init__(self, field, attname, source_field_name): self.attname = attname self.field = field + self.source_field_name = source_field_name def __get__(self, instance, owner): if instance is None: return self.field else: - field_name = getattr(self.field, 'source', None) - if field_name: - source = getattr(instance, field_name) - else: - image_fields = [getattr(instance, f.attname) for f in - instance.__class__._meta.fields if - isinstance(f, ImageField)] - if len(image_fields) == 0: - raise Exception('%s does not define any ImageFields, so your' - ' %s ImageSpecField has no image to act on.' % - (instance.__class__.__name__, self.attname)) - elif len(image_fields) > 1: - raise Exception('%s defines multiple ImageFields, but you' - ' have not specified a source for your %s' - ' ImageSpecField.' % (instance.__class__.__name__, - self.attname)) - else: - source = image_fields[0] + source = getattr(instance, self.source_field_name) spec = self.field.get_spec(source=source) file = ImageCacheFile(spec) instance.__dict__[self.attname] = file diff --git a/tests/models.py b/tests/models.py index 7520a5cf..f1e20c2c 100644 --- a/tests/models.py +++ b/tests/models.py @@ -12,9 +12,10 @@ class ImageModel(models.Model): class Photo(models.Model): original_image = models.ImageField(upload_to='photos') + # Implicit source field thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1), - ResizeToFill(50, 50)], source='original_image', format='JPEG', - options={'quality': 90}) + ResizeToFill(50, 50)], format='JPEG', + options={'quality': 90}) smartcropped_thumbnail = ImageSpecField([Adjust(contrast=1.2, sharpness=1.1), SmartCrop(50, 50)], source='original_image', From 9891314b8e77d82edf7eafe3bd237da0ac585da5 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 12:25:02 -0400 Subject: [PATCH 259/527] Don't error if same generator is registered --- imagekit/registry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index a28738f9..620f9f86 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -15,7 +15,8 @@ def __init__(self): before_access.connect(self.before_access_receiver) def register(self, id, generator): - if id in self._generators: + registered_generator = self._generators.get(id) + if registered_generator and generator != self._generators[id]: raise AlreadyRegistered('The generator with id %s is' ' already registered' % id) self._generators[id] = generator From dafebc9a4de03fcd5c31fd038af5c8ccba3d30a2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 14:11:26 -0400 Subject: [PATCH 260/527] Don't call register without spec --- imagekit/specs/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index c12acfad..3c658367 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -202,7 +202,9 @@ def set_spec_id(self, id): """ self.spec_id = id - register.generator(id, self._original_spec) + + if self._original_spec: + register.generator(id, self._original_spec) def get_spec(self, source): """ From 41ab2c0fa3282108efd4574f64d2b4b9662adf73 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 14:57:11 -0400 Subject: [PATCH 261/527] Use different name for different signature --- imagekit/models/fields/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 1042d834..95569916 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -7,7 +7,9 @@ class SpecHostField(SpecHost): - def set_spec_id(self, cls, name): + def _set_spec_id(self, cls, name): + spec_id = getattr(self, 'spec_id', None) + # Generate a spec_id to register the spec with. The default spec id is # ":_" if not getattr(self, 'spec_id', None): @@ -59,7 +61,7 @@ def contribute_to_class(self, cls, name): source = image_fields[0] setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) - self.set_spec_id(cls, name) + self._set_spec_id(cls, name) # Add the model and field as a source for this spec id register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) @@ -92,7 +94,7 @@ def __init__(self, processors=None, format=None, options=None, height_field, **kwargs) def contribute_to_class(self, cls, name): - self.set_spec_id(cls, name) + self._set_spec_id(cls, name) return super(ProcessedImageField, self).contribute_to_class(cls, name) From 091b2137d08e146dbe7dc57b29e1a7714999bb46 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 14:57:41 -0400 Subject: [PATCH 262/527] Always call set_spec_id --- imagekit/models/fields/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 95569916..3f1a2f62 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -12,13 +12,13 @@ def _set_spec_id(self, cls, name): # Generate a spec_id to register the spec with. The default spec id is # ":_" - if not getattr(self, 'spec_id', None): + if not spec_id: spec_id = (u'%s:%s:%s' % (cls._meta.app_label, cls._meta.object_name, name)).lower() - # Register the spec with the id. This allows specs to be overridden - # later, from outside of the model definition. - super(SpecHostField, self).set_spec_id(spec_id) + # Register the spec with the id. This allows specs to be overridden + # later, from outside of the model definition. + super(SpecHostField, self).set_spec_id(spec_id) class ImageSpecField(SpecHostField): From 6f9f99e86c5262581246505a5911e899e1eb177c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 15:28:36 -0400 Subject: [PATCH 263/527] Fields shouldn't cause AlreadyRegistered exceptions --- imagekit/specs/__init__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 3c658367..9a2ba66a 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,7 +4,7 @@ import pickle from ..cachefiles.backends import get_default_cachefile_backend from ..cachefiles.strategies import StrategyWrapper -from ..exceptions import MissingSource +from ..exceptions import AlreadyRegistered, MissingSource from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, get_by_qname from ..registry import generator_registry, register @@ -204,7 +204,15 @@ def set_spec_id(self, id): self.spec_id = id if self._original_spec: - register.generator(id, self._original_spec) + try: + register.generator(id, self._original_spec) + except AlreadyRegistered: + # Fields should not cause AlreadyRegistered exceptions. If a + # spec is already registered, that should be used. It is + # especially important that an error is not thrown here because + # of South, which will create duplicate models as part of its + # "fake orm," therefore re-registering specs. + pass def get_spec(self, source): """ From c4431fe296fcf45addd5aefc082ac42b6e96a23a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 16:41:53 -0400 Subject: [PATCH 264/527] Don't require generator to unregister --- imagekit/registry.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index 620f9f86..94adfdf6 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -21,8 +21,7 @@ def register(self, id, generator): ' already registered' % id) self._generators[id] = generator - def unregister(self, id, generator): - # TODO: Either don't require the generator, or--if we do--assert that it's registered with the provided id + def unregister(self, id): try: del self._generators[id] except KeyError: @@ -177,8 +176,8 @@ class Unregister(object): Unregister generators and generated files. """ - def generator(self, id, generator): - generator_registry.unregister(id, generator) + def generator(self, id): + generator_registry.unregister(id) def cachefiles(self, generator_id, cachefiles): cachefile_registry.unregister(generator_id, cachefiles) From 261f16412763c69fba64f130c521192ad726d2c1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 5 Apr 2013 16:43:26 -0400 Subject: [PATCH 265/527] Bump version to 3.0b1 --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index a3b1dc3b..596bb6c1 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0a5' +__version__ = '3.0b1' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 90c4529d26b76570106508a9e2868c9298e9a8f5 Mon Sep 17 00:00:00 2001 From: Eric Brelsford Date: Wed, 10 Apr 2013 14:19:25 -0400 Subject: [PATCH 266/527] processors in PILKit: documentation --- README.rst | 6 ++++++ docs/upgrading.rst | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/README.rst b/README.rst index 5e670deb..3b375409 100644 --- a/README.rst +++ b/README.rst @@ -365,6 +365,12 @@ it in your spec's ``processors`` list: format = 'JPEG' options = {'quality': 60} +Note that when you import a processor from ``imagekit.processors``, imagekit +in turn imports the processor from `PILKit`_. So if you are looking for +available processors, look at PILKit. + +.. _`PILKit`: https://github.com/matthewwithanm/pilkit + Admin ----- diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 4efe7c0a..2a48a75d 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -112,3 +112,13 @@ and other spec options to ensure that changes to the spec always result in unique file names. See the documentation on `specs`_ for more. .. _`specs`: + + +Processors have moved to PILKit +------------------------------- + +Processors have moved to a separate project: `PILKit`_. You should not have to +make any changes to an IK2 project to use PILKit--it should be installed with +IK3, and importing from ``imagekit.processors`` will still work. + +.. _`PILKit`: https://github.com/matthewwithanm/pilkit From 7946fe54b5faa84436b84975ee078468f86b5d89 Mon Sep 17 00:00:00 2001 From: Eric Brelsford Date: Wed, 10 Apr 2013 14:24:02 -0400 Subject: [PATCH 267/527] processors in PILKit: module Help those looking in the code find processors. --- imagekit/processors.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 imagekit/processors.py diff --git a/imagekit/processors.py b/imagekit/processors.py new file mode 100644 index 00000000..dbf0b030 --- /dev/null +++ b/imagekit/processors.py @@ -0,0 +1,5 @@ +""" +Looking for processors? They have moved to PILKit. See imagekit.importers for +details. + +""" From 13c92db760bc65f2436b93d764ee5ca2d3946e08 Mon Sep 17 00:00:00 2001 From: danxshap Date: Sun, 21 Apr 2013 16:06:13 -0400 Subject: [PATCH 268/527] Re-open source file on ValueError in ImageSpec.generate() --- imagekit/specs/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 9a2ba66a..dbe56edf 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -130,7 +130,14 @@ def generate(self): # TODO: Move into a generator base class # TODO: Factor out a generate_image function so you can create a generator and only override the PIL.Image creating part. (The tricky part is how to deal with original_format since generator base class won't have one.) - img = open_image(self.source) + try: + img = open_image(self.source) + except ValueError: + + # Re-open the file -- https://code.djangoproject.com/ticket/13750 + self.source.open() + img = open_image(self.source) + original_format = img.format # Run the processors From 0a98eb0e792d006ffc9517b129e8ce96af44a033 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 22 Apr 2013 09:05:49 -0400 Subject: [PATCH 269/527] Use DEFAULT_FILE_STORAGE by default As raised in #203, if `IMAGEKIT_DEFAULT_FILE_STORAGE` isn't set, `DEFAULT_FILE_STORAGE` should be used. --- imagekit/conf.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 4c2f2e77..3e454c0f 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -9,7 +9,7 @@ class ImageKitConf(AppConf): DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Simple' DEFAULT_CACHEFILE_STRATEGY = 'imagekit.cachefiles.strategies.JustInTime' - DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' + DEFAULT_FILE_STORAGE = None CACHE_BACKEND = None CACHE_PREFIX = 'imagekit:' @@ -21,3 +21,8 @@ def configure_cache_backend(self, value): else: value = 'dummy://' if settings.DEBUG else settings.CACHE_BACKEND return value + + def configure_default_file_storage(self, value): + if value is None: + value = settings.DEFAULT_FILE_STORAGE + return value From f5b171979be58732fb28dce0295168ef9ab30494 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 25 Apr 2013 02:29:27 -0400 Subject: [PATCH 270/527] Canonicalize sets and dicts before hashing --- imagekit/hashers.py | 31 +++++++++++++++++++++++++++++++ imagekit/specs/__init__.py | 7 +++---- 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 imagekit/hashers.py diff --git a/imagekit/hashers.py b/imagekit/hashers.py new file mode 100644 index 00000000..4231fa59 --- /dev/null +++ b/imagekit/hashers.py @@ -0,0 +1,31 @@ +from copy import copy +from hashlib import md5 +from pickle import Pickler, MARK, DICT +from types import DictionaryType +from .lib import StringIO + + +class CanonicalizingPickler(Pickler): + dispatch = copy(Pickler.dispatch) + + def save_set(self, obj): + rv = obj.__reduce_ex__(0) + rv = (rv[0], (sorted(rv[1][0]),), rv[2]) + self.save_reduce(obj=obj, *rv) + + dispatch[set] = save_set + + def save_dict(self, obj): + write = self.write + write(MARK + DICT) + + self.memoize(obj) + self._batch_setitems(sorted(obj.iteritems())) + + dispatch[DictionaryType] = save_dict + + +def pickle(obj): + file = StringIO() + CanonicalizingPickler(file, 0).dump(obj) + return md5(file.getvalue()).hexdigest() diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index dbe56edf..2f6dc519 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,9 +1,8 @@ from django.conf import settings from django.db.models.fields.files import ImageFieldFile -from hashlib import md5 -import pickle from ..cachefiles.backends import get_default_cachefile_backend from ..cachefiles.strategies import StrategyWrapper +from .. import hashers from ..exceptions import AlreadyRegistered, MissingSource from ..processors import ProcessorPipeline from ..utils import open_image, img_to_fobj, get_by_qname @@ -115,13 +114,13 @@ def __setstate__(self, state): self.source = getattr(field_data['instance'], field_data['attname']) def get_hash(self): - return md5(pickle.dumps([ + return hashers.pickle([ self.source.name, self.processors, self.format, self.options, self.autoconvert, - ])).hexdigest() + ]) def generate(self): if not self.source: From a3498c5aa1abd837712717a6d371845b5ed940e9 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Thu, 25 Apr 2013 11:29:27 -0700 Subject: [PATCH 271/527] Add a build status image to the README. Fixes #206. --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index 3b375409..f3beb3d5 100644 --- a/README.rst +++ b/README.rst @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/jdriscoll/django-imagekit.png?branch=develop)](https://travis-ci.org/jdriscoll/django-imagekit) + ImageKit is a Django app for processing images. Need a thumbnail? A black-and-white version of a user-uploaded image? ImageKit will make them for you. If you need to programatically generate one image from another, you need From bc0c17010ef2caf01dc4eadb5c8c394de92dce52 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Thu, 25 Apr 2013 11:33:29 -0700 Subject: [PATCH 272/527] Bryan, we use reST. >_<; Refs #206. --- README.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f3beb3d5..25ef13d9 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,7 @@ -[![Build Status](https://travis-ci.org/jdriscoll/django-imagekit.png?branch=develop)](https://travis-ci.org/jdriscoll/django-imagekit) +|Build Status|_ + +.. |Build Status| image:: https://travis-ci.org/jdriscoll/django-imagekit.png?branch=canon-pickle +.. _Build Status: https://travis-ci.org/jdriscoll/django-imagekit ImageKit is a Django app for processing images. Need a thumbnail? A black-and-white version of a user-uploaded image? ImageKit will make them for From c704db2da557cf25eea24be7239a28af6af0e521 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 09:09:08 -0400 Subject: [PATCH 273/527] Sanitize cache keys for memcached Closes #208 --- imagekit/cachefiles/backends.py | 5 +++-- imagekit/conf.py | 1 + imagekit/utils.py | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 5a57c204..18c8e709 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -1,4 +1,4 @@ -from ..utils import get_singleton +from ..utils import get_singleton, sanitize_cache_key from django.core.cache import get_cache from django.core.exceptions import ImproperlyConfigured @@ -57,7 +57,8 @@ def cache(self): def get_key(self, file): from django.conf import settings - return '%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, file.name) + return sanitize_cache_key('%s%s-state' % + (settings.IMAGEKIT_CACHE_PREFIX, file.name)) def get_state(self, file): key = self.get_key(file) diff --git a/imagekit/conf.py b/imagekit/conf.py index 3e454c0f..dd082e7a 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -13,6 +13,7 @@ class ImageKitConf(AppConf): CACHE_BACKEND = None CACHE_PREFIX = 'imagekit:' + USE_MEMCACHED_SAFE_CACHE_KEY = True def configure_cache_backend(self, value): if value is None: diff --git a/imagekit/utils.py b/imagekit/utils.py index ae81760e..6590a8a0 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,10 +1,16 @@ import logging from tempfile import NamedTemporaryFile +from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files import File from django.utils.importlib import import_module +from hashlib import md5 from pilkit.utils import * +import re + + +bad_memcached_key_chars = re.compile(ur'[\u0000-\u0031\s]+') def get_nonabstract_descendants(model): @@ -123,3 +129,17 @@ def call_strategy_method(generator, method_name, *args, **kwargs): fn = getattr(strategy, method_name, None) if fn is not None: fn(*args, **kwargs) + + +def sanitize_cache_key(key): + if settings.IMAGEKIT_USE_MEMCACHED_SAFE_CACHE_KEY: + # Memcached keys can't contain whitespace or control characters. + new_key = bad_memcached_key_chars.sub('', key) + + # The also can't be > 250 chars long. Since we don't know what the + # user's cache ``KEY_FUNCTION`` setting is like, we'll limit it to 200. + if len(new_key) >= 200: + new_key = '%s:%s' % (new_key[:200-33], md5(key).hexdigest()) + + key = new_key + return key From f173861b53b9d681ca6ceba0d6d039e3a935b25e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 09:31:52 -0400 Subject: [PATCH 274/527] Fix invalid char range --- imagekit/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 6590a8a0..73e0af24 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -10,7 +10,7 @@ import re -bad_memcached_key_chars = re.compile(ur'[\u0000-\u0031\s]+') +bad_memcached_key_chars = re.compile(ur'[\u0000-\u001f\s]+') def get_nonabstract_descendants(model): From eb36ae399e8a5881ef33f0c43aab910ce2f3ae1f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 09:32:13 -0400 Subject: [PATCH 275/527] Add test for memcached key sanitation --- tests/test_cachefiles.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index d3c29028..957b1320 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,5 +1,10 @@ +from django.conf import settings +from hashlib import md5 from imagekit.cachefiles import ImageCacheFile -from nose.tools import raises +from imagekit.cachefiles.backends import Simple +from nose.tools import raises, eq_ +import random +import string from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, DummyAsyncCacheFileBackend, get_unique_image_file) @@ -41,3 +46,32 @@ def test_no_source_error(): spec = TestSpec(source=None) file = ImageCacheFile(spec) file.generate() + + +def test_memcached_cache_key(): + """ + Ensure the default cachefile backend is sanitizing its cache key for + memcached by default. + + """ + + class MockFile(object): + def __init__(self, name): + self.name = name + + backend = Simple() + extra_char_count = len('state-') + len(settings.IMAGEKIT_CACHE_PREFIX) + + length = 199 - extra_char_count + filename = '1' * length + file = MockFile(filename) + eq_(backend.get_key(file), '%s%s-state' % + (settings.IMAGEKIT_CACHE_PREFIX, file.name)) + + length = 200 - extra_char_count + filename = '1' * length + file = MockFile(filename) + eq_(backend.get_key(file), '%s%s:%s' % ( + settings.IMAGEKIT_CACHE_PREFIX, + '1' * (200 - len(':') - 32 - len(settings.IMAGEKIT_CACHE_PREFIX)), + md5('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename)).hexdigest())) From deed81b9635aea80ff43943f6e53ae5e4165bf3b Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 30 Apr 2013 18:30:51 -0400 Subject: [PATCH 276/527] Added caching docs --- docs/advanced_usage.rst | 292 ++++++++++------------------------------ docs/caching.rst | 179 ++++++++++++++++++++++++ docs/index.rst | 1 + 3 files changed, 254 insertions(+), 218 deletions(-) create mode 100644 docs/caching.rst diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index e7d35cb4..1bcf276a 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -2,6 +2,80 @@ Advanced Usage ************** +.. _source-groups: + +Source Groups +============= + +When you run the ``generateimages`` management command, how does ImageKit know +which source images to use with which specs? Obviously, when you define an +ImageSpecField, the source image is being connected to a spec, but what's going +on underneath the hood? + +The answer is that, when you define an ImageSpecField, ImageKit automatically +creates and registers an object called a *source group*. Source groups are +responsible for two things: + +1. They dispatch signals when a source is created, changed, or deleted, and +2. They expose a generator method that enumerates source files. + +When these objects are registered (using ``imagekit.register.source_group()``), +their signals will trigger callbacks on the cache file strategies associated +with image specs that use the source. (So, for example, you can chose to +generate a file every time the source image changes.) In addition, the generator +method is used (indirectly) to create the list of files to generate with the +``generateimages`` management command. + +Currently, there is only one source group class bundled with ImageKit—the one +used by ImageSpecFields. This source group +(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField +on every instance of a particular model. In terms of the above description, the +instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal +every time the image in Profile's avatar ImageField changes, and 2) exposes a +generator method that iterates over every Profile's "avatar" image. + +Chances are, this is the only source group you will ever need to use, however, +ImageKit lets you define and register custom source groups easily. This may be +useful, for example, if you're using the template tags "generateimage" and +"thumbnail" and the optimistic cache file strategy. Again, the purpose is +to tell ImageKit which specs are used with which sources (so the +"generateimages" management command can generate those files) and when the +source image has been created or changed (so that the strategy has the +opportunity to act on it). + +A simple example of a custom source group class is as follows: + +.. code-block:: python + + import glob + import os + + class JpegsInADirectory(object): + def __init__(self, dir): + self.dir = dir + + def files(self): + os.chdir(self.dir) + for name in glob.glob('*.jpg'): + yield open(name) + +Instances of this class could then be registered with one or more spec id: + +.. code-block:: python + + from imagekit import register + + register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) + +Running the "generateimages" management command would now cause thumbnails to be +generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the +JPEGs in `/path/to/some/pics`. + +Note that, since this source group doesnt send the `source_created` or +`source_changed` signals, the corresponding cache file strategy callbacks +would not be called for them. + + Models ====== @@ -108,221 +182,3 @@ the model! Of course, processors aren't the only thing that can vary based on the model of the source image; spec behavior can change in any way you want. - -Optimizing -========== - -Unlike Django's ImageFields, ImageKit's ImageSpecFields and template tags don't -persist any data in the database. Therefore, in order to know whether an image -file needs to be generated, ImageKit needs to check if the file already exists -(using the appropriate `file storage object`__). The object responsible for -performing these checks is called a *cache file backend*. - - -__ https://docs.djangoproject.com/en/dev/topics/files/#file-storage - - -Cache! ------- - -By default, ImageKit checks for the existence of a cache file every time you -attempt to use the file and, if it doesn't exist, creates it synchronously. This -is a very safe behavior because it ensures that your ImageKit-generated images -are always available. However, that's a lot of checking with storage and those -kinds of operations can be slow—especially if you're using a remote storage—so -you'll want to try to avoid them as much as possible. - -Luckily, the default cache file backend makes use of Django's caching -abilities to mitigate the number of checks it actually has to do; it will use -the cache specified by the ``IMAGEKIT_CACHE_BACKEND`` to save the state of the -generated file. If your Django project is running in debug mode -(``settings.DEBUG`` is true), this will be a dummy cache by default. Otherwise, -it will use your project's default cache. - -In normal operation, your cache files will never be deleted; once they're -created, they'll stay created. So the simplest optimization you can make is to -set your ``IMAGEKIT_CACHE_BACKEND`` to a cache with a very long, or infinite, -timeout. - - -Deferring Image Generation --------------------------- - -As mentioned above, image generation is normally done synchronously. However, -you can also take advantage of deferred generation. In order to do this, you'll -need to do two things: 1) install `django-celery`__ and 2) tell ImageKit to use -the async cachefile backend. You can do this either on a per-spec basis (by -setting the ``cachefile_backend`` attribute), or for your project by setting -``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` in your settings.py: - -.. code-block:: python - - IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Async' - -Images will now be generated asynchronously. But watch out! Asynchrounous -generation means you'll have to account for images that haven't been generated -yet. You can do this by checking the truthiness of your files; if an image -hasn't been generated, it will be falsy: - -.. code-block:: html - - {% if not profile.avatar_thumbnail %} - - {% else %} - - {% endif %} - -Or, in Python: - -.. code-block:: python - - profile = Profile.objects.all()[0] - if profile.avatar_thumbnail: - url = profile.avatar_thumbnail.url - else: - url = '/path/to/placeholder.jpg' - - -__ https://pypi.python.org/pypi/django-celery - - -Even More Advanced ------------------- - -For many applications—particularly those using local storage for generated image -files—a cache with a long timeout is all the optimization you'll need. However, -there may be times when that simply doesn't cut it. In these cases, you'll want -to change when the generation is actually done. - -The objects responsible for specifying when cache files are created are -called *cache file strategies*. The default strategy can be set using the -``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting, and its default value is -`'imagekit.cachefiles.strategies.JustInTime'`. As we've already seen above, -the "just in time" strategy determines whether a file needs to be generated each -time it's accessed and, if it does, generates it synchronously (that is, as part -of the request-response cycle). - -Another strategy is to simply assume the file exists. This requires the fewest -number of checks (zero!), so we don't have to worry about expensive IO. The -strategy that takes this approach is -``imagekit.cachefiles.strategies.Optimistic``. In order to use this -strategy, either set the ``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` setting or, -to use it on a per-generator basis, set the ``cachefile_strategy`` attribute -of your spec or generator. Avoiding checking for file existence can be a real -boon to performance, but it also means that ImageKit has no way to know when a -file needs to be generated—well, at least not all the time. - -With image specs, we can know at least some of the times that a new file needs -to be generated: whenever the source image is created or changed. For this -reason, the optimistic strategy defines callbacks for these events. Every -source registered with ImageKit will automatically cause its specs' files to be -generated when it is created or changed. - -.. note:: - - In order to understand source registration, read :ref:`source-groups` - -If you have specs that :ref:`change based on attributes of the source -`, that's not going to cut it, though; the file will also need to -be generated when those attributes change. Likewise, image generators that don't -have sources (i.e. generators that aren't specs) won't cause files to be -generated automatically when using the optimistic strategy. (ImageKit can't know -when those need to be generated, if not on access.) In both cases, you'll have -to trigger the file generation yourself—either by generating the file in code -when necessary, or by periodically running the ``generateimages`` management -command. Luckily, ImageKit makes this pretty easy: - -.. code-block:: python - - from imagekit.cachefiles import LazyImageCacheFile - - file = LazyImageCacheFile('myapp:profile:avatar_thumbnail', source=source_file) - file.generate() - -One final situation in which images won't be generated automatically when using -the optimistic strategy is when you use a spec with a source that hasn't been -registered with it. Unlike the previous two examples, this situation cannot be -rectified by running the ``generateimages`` management command, for the simple -reason that the command has no way of knowing it needs to generate a file for -that spec from that source. Typically, this situation would arise when using the -template tags. Unlike ImageSpecFields, which automatically register all the -possible source images with the spec you define, the template tags -("generateimage" and "thumbnail") let you use any spec with any source. -Therefore, in order to generate the appropriate files using the -``generateimages`` management command, you'll need to first register a source -group that represents all of the sources you wish to use with the corresponding -specs. See :ref:`source-groups` for more information. - - -.. _source-groups: - -Source Groups -============= - -When you run the ``generateimages`` management command, how does ImageKit know -which source images to use with which specs? Obviously, when you define an -ImageSpecField, the source image is being connected to a spec, but what's going -on underneath the hood? - -The answer is that, when you define an ImageSpecField, ImageKit automatically -creates and registers an object called a *source group*. Source groups are -responsible for two things: - -1. They dispatch signals when a source is created, changed, or deleted, and -2. They expose a generator method that enumerates source files. - -When these objects are registered (using ``imagekit.register.source_group()``), -their signals will trigger callbacks on the cache file strategies associated -with image specs that use the source. (So, for example, you can chose to -generate a file every time the source image changes.) In addition, the generator -method is used (indirectly) to create the list of files to generate with the -``generateimages`` management command. - -Currently, there is only one source group class bundled with ImageKit—the one -used by ImageSpecFields. This source group -(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField -on every instance of a particular model. In terms of the above description, the -instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal -every time the image in Profile's avatar ImageField changes, and 2) exposes a -generator method that iterates over every Profile's "avatar" image. - -Chances are, this is the only source group you will ever need to use, however, -ImageKit lets you define and register custom source groups easily. This may be -useful, for example, if you're using the template tags "generateimage" and -"thumbnail" and the optimistic cache file strategy. Again, the purpose is -to tell ImageKit which specs are used with which sources (so the -"generateimages" management command can generate those files) and when the -source image has been created or changed (so that the strategy has the -opportunity to act on it). - -A simple example of a custom source group class is as follows: - -.. code-block:: python - - import glob - import os - - class JpegsInADirectory(object): - def __init__(self, dir): - self.dir = dir - - def files(self): - os.chdir(self.dir) - for name in glob.glob('*.jpg'): - yield open(name) - -Instances of this class could then be registered with one or more spec id: - -.. code-block:: python - - from imagekit import register - - register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) - -Running the "generateimages" management command would now cause thumbnails to be -generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the -JPEGs in `/path/to/some/pics`. - -Note that, since this source group doesnt send the `source_created` or -`source_changed` signals, the corresponding cache file strategy callbacks -would not be called for them. diff --git a/docs/caching.rst b/docs/caching.rst new file mode 100644 index 00000000..af99ab79 --- /dev/null +++ b/docs/caching.rst @@ -0,0 +1,179 @@ +Caching +******* + +Default Backend Workflow +================ + +``ImageSpec`` +------------- + +At the heart of ImageKit are image generators. These are callables which return +a modified image. An image spec is a type of image generator. The thing that +makes specs special is that they accept a source image. So an image spec is +just an image generator that makes an image from some other image. + +``ImageCacheFile`` +------------------ + +However, an image spec by itself would be vastly inefficient. Every time an +an image was accessed in some way, it would have be regenerated at saved. +Most of the time, you want to re-use a previously generated image, based on the +inpurt image and spec, instead generating a new one. That's where +``ImageCacheFile`` comes in. ``ImageCacheFile`` is a File-like object that +is returned from an image generator. They look and feel just like regular file +objects, but they've got a little trick up their sleeve: they represent files +that may not actually exist! + +Cache File Strategy +------------------- +Each ``ImageCacheFile`` has a cache file strategy, which abstracts away when +image is actually generated. It implenents four methods. + +* ``before_access`` - called by ``ImageCacheFile`` when you access its url, + width, or height attribute. +* ``on_source_created`` - called when the source of a spec is created +* ``on_source_changed`` - called when the source of a spec is changed +* ``on_source_deleted`` - called when the source of a spec is deleted + +The default strategy only defines the first of these, as follows: + +.. code-block:: python + + class JustInTime(object): + def before_access(self, file): + file.generate() + + +Cache File Backend +------------------ +The ``generate`` method on the ``ImageCacheFile`` is further delegated to the +cache file backend, which abstracts away how an image is generated. + +The cache file backend defaults to the setting +``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` and can be set explicitly on a spec with +the ``cachefile_backend`` attribute. + +The default works like this: + +* Checks the file storage to see if a file exists + * If not, caches that information for 5 seconds + * If it does, caches that information in the ``IMAGEKIT_CACHE_BACKEND`` + +If file doesn't exsit, generates it immediately and synchronously + + +That pretty much covers the architecture of the caching layer, and its default +behavior. I like the default behavior. When will an image be regenerated? +Whenever it needs to be! When will your storage backend get hit? Depending on +our IMAGEKIT_CACHE_BACKEND settings, as little as twice per file (once for the +existence check and once to save the generated file). +(Actually, like regular Django ImageFields, IK never caches width and height +so those will always result in a read. That will probably change soon though.) +What if you want to change a spec? The generated file name (which is used as +part of the cache keys) vary with the source file name and spec attributes, +so if you change any of those, a new file will be generated. The default +behavior is easy! + + + +Deferring Image Generation +========================== +As mentioned above, image generation is normally done synchronously. through +the default cache file backend. However, you can also take advantage of +deferred generation. In order to do this, you'll need to do two things: + +1) install `django-celery`__ +2) tell ImageKit to use the async cachefile backend. + To do this for all specs, set the ``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` in + your settings + +.. code-block:: python + + IMAGEKIT_DEFAULT_CACHEFILE_BACKEND = 'imagekit.cachefiles.backends.Async' + +Images will now be generated asynchronously. But watch out! Asynchrounous +generation means you'll have to account for images that haven't been generated +yet. You can do this by checking the truthiness of your files; if an image +hasn't been generated, it will be falsy: + +.. code-block:: html + + {% if not profile.avatar_thumbnail %} + + {% else %} + + {% endif %} + +Or, in Python: + +.. code-block:: python + + profile = Profile.objects.all()[0] + if profile.avatar_thumbnail: + url = profile.avatar_thumbnail.url + else: + url = '/path/to/placeholder.jpg' + + +__ https://pypi.python.org/pypi/django-celery + + +Pre-Generating Images +===================== + +The default behavior generates images "immediately and synchronously". They are +generated as part of the request-response cycle, which slows down the request. + +This can be mitigated by generating the images generating the images outside of +a request. This can be done by running the ``generateimages`` + +.. note:: + + If using with template tags, be sure to read :ref:`source-groups`. + + +Minimizing Storage Backend Access +================================= +However even with pre-generating images, the storage backend still has to be +queried to see if the file exists every time it is accessed. If you never +want ImageKit to generate images in the request-responce cycle, then it never +has to check if the image exists. The other cache file strategy only generates +a new image when their source image is created or changed. + +To use this cache file strategy for all specs, set the +``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` in your settings + +.. code-block:: python + + IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = 'imagekit.cachefiles.strategies.Optimistic' + +If you have specs that :ref:`change based on attributes of the source +`, that's not going to cut it, though; the file will also need to +be generated when those attributes change. Likewise, image generators that don't +have sources (i.e. generators that aren't specs) won't cause files to be +generated automatically when using the optimistic strategy. (ImageKit can't know +when those need to be generated, if not on access.) In both cases, you'll have +to trigger the file generation yourself—either by generating the file in code +when necessary, or by periodically running the ``generateimages`` management +command. Luckily, ImageKit makes this pretty easy: + +.. code-block:: python + + from imagekit.cachefiles import LazyImageCacheFile + + file = LazyImageCacheFile('myapp:profile:avatar_thumbnail', source=source_file) + file.generate() + +One final situation in which images won't be generated automatically when using +the optimistic strategy is when you use a spec with a source that hasn't been +registered with it. Unlike the previous two examples, this situation cannot be +rectified by running the ``generateimages`` management command, for the simple +reason that the command has no way of knowing it needs to generate a file for +that spec from that source. Typically, this situation would arise when using the +template tags. Unlike ImageSpecFields, which automatically register all the +possible source images with the spec you define, the template tags +("generateimage" and "thumbnail") let you use any spec with any source. +Therefore, in order to generate the appropriate files using the +``generateimages`` management command, you'll need to first register a source +group that represents all of the sources you wish to use with the corresponding +specs. See :ref:`source-groups` for more information. diff --git a/docs/index.rst b/docs/index.rst index 04eee0f4..9773f7f1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,5 +20,6 @@ Indices and tables configuration advanced_usage + caching changelog upgrading From 4a608caf3a2914cc1411ca31f15fedf48a2b54fb Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Tue, 30 Apr 2013 18:34:42 -0400 Subject: [PATCH 277/527] moved models in front of source groups in the advanced docs --- docs/advanced_usage.rst | 149 ++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 1bcf276a..15dfb138 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -2,80 +2,6 @@ Advanced Usage ************** -.. _source-groups: - -Source Groups -============= - -When you run the ``generateimages`` management command, how does ImageKit know -which source images to use with which specs? Obviously, when you define an -ImageSpecField, the source image is being connected to a spec, but what's going -on underneath the hood? - -The answer is that, when you define an ImageSpecField, ImageKit automatically -creates and registers an object called a *source group*. Source groups are -responsible for two things: - -1. They dispatch signals when a source is created, changed, or deleted, and -2. They expose a generator method that enumerates source files. - -When these objects are registered (using ``imagekit.register.source_group()``), -their signals will trigger callbacks on the cache file strategies associated -with image specs that use the source. (So, for example, you can chose to -generate a file every time the source image changes.) In addition, the generator -method is used (indirectly) to create the list of files to generate with the -``generateimages`` management command. - -Currently, there is only one source group class bundled with ImageKit—the one -used by ImageSpecFields. This source group -(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField -on every instance of a particular model. In terms of the above description, the -instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal -every time the image in Profile's avatar ImageField changes, and 2) exposes a -generator method that iterates over every Profile's "avatar" image. - -Chances are, this is the only source group you will ever need to use, however, -ImageKit lets you define and register custom source groups easily. This may be -useful, for example, if you're using the template tags "generateimage" and -"thumbnail" and the optimistic cache file strategy. Again, the purpose is -to tell ImageKit which specs are used with which sources (so the -"generateimages" management command can generate those files) and when the -source image has been created or changed (so that the strategy has the -opportunity to act on it). - -A simple example of a custom source group class is as follows: - -.. code-block:: python - - import glob - import os - - class JpegsInADirectory(object): - def __init__(self, dir): - self.dir = dir - - def files(self): - os.chdir(self.dir) - for name in glob.glob('*.jpg'): - yield open(name) - -Instances of this class could then be registered with one or more spec id: - -.. code-block:: python - - from imagekit import register - - register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) - -Running the "generateimages" management command would now cause thumbnails to be -generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the -JPEGs in `/path/to/some/pics`. - -Note that, since this source group doesnt send the `source_created` or -`source_changed` signals, the corresponding cache file strategy callbacks -would not be called for them. - - Models ====== @@ -128,7 +54,6 @@ want to go through the trouble of using the long form? The answer is that the long form—creating an image spec class and registering it—gives you a lot more power over the generated image. - .. _dynamic-specs: Specs That Change @@ -182,3 +107,77 @@ the model! Of course, processors aren't the only thing that can vary based on the model of the source image; spec behavior can change in any way you want. + +.. _source-groups: + +Source Groups +============= + +When you run the ``generateimages`` management command, how does ImageKit know +which source images to use with which specs? Obviously, when you define an +ImageSpecField, the source image is being connected to a spec, but what's going +on underneath the hood? + +The answer is that, when you define an ImageSpecField, ImageKit automatically +creates and registers an object called a *source group*. Source groups are +responsible for two things: + +1. They dispatch signals when a source is created, changed, or deleted, and +2. They expose a generator method that enumerates source files. + +When these objects are registered (using ``imagekit.register.source_group()``), +their signals will trigger callbacks on the cache file strategies associated +with image specs that use the source. (So, for example, you can chose to +generate a file every time the source image changes.) In addition, the generator +method is used (indirectly) to create the list of files to generate with the +``generateimages`` management command. + +Currently, there is only one source group class bundled with ImageKit—the one +used by ImageSpecFields. This source group +(``imagekit.specs.sourcegroups.ImageFieldSourceGroup``) represents an ImageField +on every instance of a particular model. In terms of the above description, the +instance ``ImageFieldSourceGroup(Profile, 'avatar')`` 1) dispatches a signal +every time the image in Profile's avatar ImageField changes, and 2) exposes a +generator method that iterates over every Profile's "avatar" image. + +Chances are, this is the only source group you will ever need to use, however, +ImageKit lets you define and register custom source groups easily. This may be +useful, for example, if you're using the template tags "generateimage" and +"thumbnail" and the optimistic cache file strategy. Again, the purpose is +to tell ImageKit which specs are used with which sources (so the +"generateimages" management command can generate those files) and when the +source image has been created or changed (so that the strategy has the +opportunity to act on it). + +A simple example of a custom source group class is as follows: + +.. code-block:: python + + import glob + import os + + class JpegsInADirectory(object): + def __init__(self, dir): + self.dir = dir + + def files(self): + os.chdir(self.dir) + for name in glob.glob('*.jpg'): + yield open(name) + +Instances of this class could then be registered with one or more spec id: + +.. code-block:: python + + from imagekit import register + + register.source_group('myapp:profile:avatar_thumbnail', JpegsInADirectory('/path/to/some/pics')) + +Running the "generateimages" management command would now cause thumbnails to be +generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the +JPEGs in `/path/to/some/pics`. + +Note that, since this source group doesnt send the `source_created` or +`source_changed` signals, the corresponding cache file strategy callbacks +would not be called for them. + From 676d49c60553ad8c83049c66d799ef4349ddcd14 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 21:56:55 -0400 Subject: [PATCH 278/527] A few corrections; more about caching file data --- docs/caching.rst | 114 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/docs/caching.rst b/docs/caching.rst index af99ab79..7bf7ea61 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -1,33 +1,39 @@ Caching ******* + Default Backend Workflow ================ + ``ImageSpec`` ------------- -At the heart of ImageKit are image generators. These are callables which return -a modified image. An image spec is a type of image generator. The thing that -makes specs special is that they accept a source image. So an image spec is -just an image generator that makes an image from some other image. +At the heart of ImageKit are image generators. These are classes with a +``generate()`` method which returns an image file. An image spec is a type of +image generator. The thing that makes specs special is that they accept a source +image. So an image spec is just an image generator that makes an image from some +other image. + ``ImageCacheFile`` ------------------ However, an image spec by itself would be vastly inefficient. Every time an -an image was accessed in some way, it would have be regenerated at saved. +an image was accessed in some way, it would have be regenerated and saved. Most of the time, you want to re-use a previously generated image, based on the -inpurt image and spec, instead generating a new one. That's where +input image and spec, instead of generating a new one. That's where ``ImageCacheFile`` comes in. ``ImageCacheFile`` is a File-like object that -is returned from an image generator. They look and feel just like regular file +wraps an image generator. They look and feel just like regular file objects, but they've got a little trick up their sleeve: they represent files that may not actually exist! + Cache File Strategy ------------------- + Each ``ImageCacheFile`` has a cache file strategy, which abstracts away when -image is actually generated. It implenents four methods. +image is actually generated. It can implement the following four methods: * ``before_access`` - called by ``ImageCacheFile`` when you access its url, width, or height attribute. @@ -46,6 +52,7 @@ The default strategy only defines the first of these, as follows: Cache File Backend ------------------ + The ``generate`` method on the ``ImageCacheFile`` is further delegated to the cache file backend, which abstracts away how an image is generated. @@ -65,19 +72,57 @@ If file doesn't exsit, generates it immediately and synchronously That pretty much covers the architecture of the caching layer, and its default behavior. I like the default behavior. When will an image be regenerated? Whenever it needs to be! When will your storage backend get hit? Depending on -our IMAGEKIT_CACHE_BACKEND settings, as little as twice per file (once for the -existence check and once to save the generated file). -(Actually, like regular Django ImageFields, IK never caches width and height -so those will always result in a read. That will probably change soon though.) -What if you want to change a spec? The generated file name (which is used as -part of the cache keys) vary with the source file name and spec attributes, -so if you change any of those, a new file will be generated. The default -behavior is easy! +your ``IMAGEKIT_CACHE_BACKEND`` settings, as little as twice per file (once for the +existence check and once to save the generated file). What if you want to change +a spec? The generated file name (which is used as part of the cache keys) vary +with the source file name and spec attributes, so if you change any of those, a +new file will be generated. The default behavior is easy! + +.. note:: + + Like regular Django ImageFields, IK doesn't currently cache width and height + values, so accessing those will always result in a read. That will probably + change soon though. + + +Optimizing +========== + +There are several ways to improve the performance (reduce I/O operations) of +ImageKit. Each has its own pros and cons. + + +Caching Data About Generated Files +---------------------------------- + +The easiest, and most significant improvement you can make to improve the +performance of your site is to have ImageKit cache the state of your generated +files. The default cache file backend will already do this (if ``DEBUG`` is +``True``), using your default Django cache backend, but you can make it way +better by setting ``IMAGEKIT_CACHE_BACKEND``. Generally, once a file is +generated, you will never be removing it; therefore, if you can, you should set +``IMAGEKIT_CACHE_BACKEND`` to a cache backend that will cache forever. + +Pre-Generating Images +--------------------- + +The default cache file backend generates images immediately and synchronously. +If you don't do anything special, that will be when they are first requested—as +part of request-response cycle. This means that the first visitor to your page +will have to wait for the file to be created before they see any HTML. + +This can be mitigated, though, by simply generating the images ahead of time, by +running the ``generateimages`` management command. + +.. note:: + + If using with template tags, be sure to read :ref:`source-groups`. Deferring Image Generation -========================== +-------------------------- + As mentioned above, image generation is normally done synchronously. through the default cache file backend. However, you can also take advantage of deferred generation. In order to do this, you'll need to do two things: @@ -118,30 +163,25 @@ Or, in Python: __ https://pypi.python.org/pypi/django-celery -Pre-Generating Images -===================== - -The default behavior generates images "immediately and synchronously". They are -generated as part of the request-response cycle, which slows down the request. - -This can be mitigated by generating the images generating the images outside of -a request. This can be done by running the ``generateimages`` - -.. note:: - - If using with template tags, be sure to read :ref:`source-groups`. +Removing Safeguards +------------------- +Even with pre-generating images, ImageKit will still try to ensure that your +image exists when you access it by default. This is for your benefit: if you +forget to generate your images, ImageKit will see that and generate it for you. +If the state of the file is cached (see above), this is a pretty cheap +operation. However, if the state isn't cached, ImageKit will need to query the +storage backend. -Minimizing Storage Backend Access -================================= -However even with pre-generating images, the storage backend still has to be -queried to see if the file exists every time it is accessed. If you never -want ImageKit to generate images in the request-responce cycle, then it never -has to check if the image exists. The other cache file strategy only generates -a new image when their source image is created or changed. +For those who aren't willing to accept that cost (and who never want ImageKit +to generate images in the request-responce cycle), there's the "optimistic" +cache file strategy. This strategy only generates a new image when a spec's +source image is created or changed. Unlike with the "just in time" strategy, +accessing the file won't cause it to be generated, ImageKit will just assume +that it already exists. To use this cache file strategy for all specs, set the -``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` in your settings +``IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY`` in your settings: .. code-block:: python From 84dcebbefec6d812e24219466823cd69a1d8e961 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 22:06:09 -0400 Subject: [PATCH 279/527] Add @saulshanabrook to AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 51784081..34c4c8de 100644 --- a/AUTHORS +++ b/AUTHORS @@ -27,6 +27,7 @@ Contributors * `Clay McClure`_ * `Jannis Leidel`_ * `Sean Bell`_ +* `Saul Shanabrook`_ .. _Justin Driscoll: http://github.com/jdriscoll .. _HZDG: http://hzdg.com @@ -47,3 +48,4 @@ Contributors .. _Clay McClure: https://github.com/claymation .. _Jannis Leidel: https://github.com/jezdez .. _Sean Bell: https://github.com/seanbell +.. _Saul Shanabrook: https://github.com/saulshanabrook From 6b75822eb3dc48f439f20ffefcc8f0cb124668a0 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 30 Apr 2013 22:52:23 -0400 Subject: [PATCH 280/527] Show build status of develop branch --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 25ef13d9..7783f23f 100644 --- a/README.rst +++ b/README.rst @@ -1,6 +1,6 @@ |Build Status|_ -.. |Build Status| image:: https://travis-ci.org/jdriscoll/django-imagekit.png?branch=canon-pickle +.. |Build Status| image:: https://travis-ci.org/jdriscoll/django-imagekit.png?branch=develop .. _Build Status: https://travis-ci.org/jdriscoll/django-imagekit ImageKit is a Django app for processing images. Need a thumbnail? A From 2304381b3dc55614c657d0d497ecc12a781945e7 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 1 May 2013 00:05:10 -0300 Subject: [PATCH 281/527] Changed contributing guidelines link to branch develop --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 7783f23f..c2b60a77 100644 --- a/README.rst +++ b/README.rst @@ -437,4 +437,4 @@ with ImageKit. __ https://github.com/jdriscoll/django-imagekit/issues?labels=contributor-friendly&state=open -__ https://github.com/jdriscoll/django-imagekit/blob/master/CONTRIBUTING.rst +__ https://github.com/jdriscoll/django-imagekit/blob/develop/CONTRIBUTING.rst From 0de80cf59ca52f8ecb45bfdf102558a7e8572852 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 1 May 2013 00:06:55 -0300 Subject: [PATCH 282/527] No makefile, so changed testing to run setup.py test --- CONTRIBUTING.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 875ec2cb..8928c84a 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -8,7 +8,7 @@ contributions merged as quickly as possible: 2. If you want to add a new feature, talk to us on the `mailing list`__ or `IRC`__ first. We might already have plans, or be able to offer some advice. 3. Make sure your code passes the tests that ImageKit already has. To run the - tests, use ``make test``. This will let you know about any errors or style + tests, use ``python setup.py test``. This will let you know about any errors or style issues. 4. While we're talking about tests, creating new ones for your code makes it much easier for us to merge your code quickly. ImageKit uses nose_, so From 92a9184ed32fbd66fde43b7d18298afc0964f8c8 Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Wed, 1 May 2013 00:19:51 -0300 Subject: [PATCH 283/527] Use tox to run all tests --- CONTRIBUTING.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 8928c84a..e36fd1cb 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -8,7 +8,7 @@ contributions merged as quickly as possible: 2. If you want to add a new feature, talk to us on the `mailing list`__ or `IRC`__ first. We might already have plans, or be able to offer some advice. 3. Make sure your code passes the tests that ImageKit already has. To run the - tests, use ``python setup.py test``. This will let you know about any errors or style + tests, first install tox, ``pip install tox``, then use ``tox``. This will let you know about any errors or style issues. 4. While we're talking about tests, creating new ones for your code makes it much easier for us to merge your code quickly. ImageKit uses nose_, so From 4efa05099d1495d229260d1b2e13865690cf101e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 9 May 2013 21:35:09 -0400 Subject: [PATCH 284/527] Use pilkit's process_image utility --- imagekit/specs/__init__.py | 16 ++++------------ setup.py | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 2f6dc519..aaa40a65 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -4,8 +4,7 @@ from ..cachefiles.strategies import StrategyWrapper from .. import hashers from ..exceptions import AlreadyRegistered, MissingSource -from ..processors import ProcessorPipeline -from ..utils import open_image, img_to_fobj, get_by_qname +from ..utils import open_image, get_by_qname, process_image from ..registry import generator_registry, register @@ -137,16 +136,9 @@ def generate(self): self.source.open() img = open_image(self.source) - original_format = img.format - - # Run the processors - processors = self.processors - img = ProcessorPipeline(processors or []).process(img) - - options = dict(self.options or {}) - format = self.format or img.format or original_format or 'JPEG' - content = img_to_fobj(img, format, **options) - return content + return process_image(img, processors=self.processors, + format=self.format, autoconvert=self.autoconvert, + options=self.options) def create_spec_class(class_attrs): diff --git a/setup.py b/setup.py index 7ed1473e..393c0199 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ test_suite='testrunner.run_tests', install_requires=[ 'django-appconf>=0.5', - 'pilkit', + 'pilkit>=0.2.0', ], extras_require={ 'async': ['django-celery>=3.0'], From d5d5fc0550861499876db2e4f544fad4f84562e2 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 00:26:46 -0400 Subject: [PATCH 285/527] Add cachefile backend fallback The generator shouldn't have to implement `cachefile_backend` --- imagekit/cachefiles/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index c60d8a93..12a01241 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -38,8 +38,11 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): storage = storage or getattr(generator, 'cachefile_storage', None) or get_singleton(settings.IMAGEKIT_DEFAULT_FILE_STORAGE, 'file storage backend') - self.cachefile_backend = cachefile_backend or getattr(generator, - 'cachefile_backend', None) + self.cachefile_backend = ( + cachefile_backend + or getattr(generator, 'cachefile_backend', None) + or get_singleton(settings.IMAGEKIT_DEFAULT_CACHEFILE_BACKEND, + 'cache file backend')) super(ImageCacheFile, self).__init__(storage=storage) From 06dd23899376917e5d631c77333baed5a93460ea Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 00:51:47 -0400 Subject: [PATCH 286/527] Store cachefile strategy on file; not generator The file can appeal to the generator for the value, but it shouldn't require it; it just does that as a convenience. --- imagekit/cachefiles/__init__.py | 10 +++++++++- imagekit/registry.py | 4 ++-- imagekit/utils.py | 6 +++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 12a01241..d1ddb6f4 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -15,7 +15,7 @@ class ImageCacheFile(BaseIKFile, ImageFile): to be deferred until the time that the cache file strategy requires it. """ - def __init__(self, generator, name=None, storage=None, cachefile_backend=None): + def __init__(self, generator, name=None, storage=None, cachefile_backend=None, cachefile_strategy=None): """ :param generator: The object responsible for generating a new image. :param name: The filename @@ -23,6 +23,8 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): file. :param cachefile_backend: The object responsible for managing the state of the file. + :param cachefile_strategy: The object responsible for handling events + for this file. """ self.generator = generator @@ -43,6 +45,12 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None): or getattr(generator, 'cachefile_backend', None) or get_singleton(settings.IMAGEKIT_DEFAULT_CACHEFILE_BACKEND, 'cache file backend')) + self.cachefile_strategy = ( + cachefile_strategy + or getattr(generator, 'cachefile_strategy', None) + or get_singleton(settings.IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY, + 'cache file strategy') + ) super(ImageCacheFile, self).__init__(storage=storage) diff --git a/imagekit/registry.py b/imagekit/registry.py index 94adfdf6..a881aa31 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -48,7 +48,7 @@ def before_access_receiver(self, sender, file, **kwargs): # FIXME: I guess this means you can't register functions? if generator.__class__ in self._generators.values(): # Only invoke the strategy method for registered generators. - call_strategy_method(generator, 'before_access', file=file) + call_strategy_method(file, 'before_access') class SourceGroupRegistry(object): @@ -105,7 +105,7 @@ def source_group_receiver(self, sender, source, signal, **kwargs): for spec in specs: file = ImageCacheFile(spec) - call_strategy_method(spec, callback_name, file=file) + call_strategy_method(file, callback_name) class CacheFileRegistry(object): diff --git a/imagekit/utils.py b/imagekit/utils.py index 73e0af24..a0f1e096 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -124,11 +124,11 @@ def generate(generator): return File(content) -def call_strategy_method(generator, method_name, *args, **kwargs): - strategy = getattr(generator, 'cachefile_strategy', None) +def call_strategy_method(file, method_name): + strategy = getattr(file, 'cachefile_strategy', None) fn = getattr(strategy, method_name, None) if fn is not None: - fn(*args, **kwargs) + fn(file) def sanitize_cache_key(key): From bc49f9cf8b83eee7222a5aecb9df9f057c1a2352 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 02:42:28 -0400 Subject: [PATCH 287/527] Store the file after we generate it This means reading ImageCacheFiles won't result in an additional storage operation. --- imagekit/cachefiles/__init__.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index d1ddb6f4..ad8359a7 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.core.files import File from django.core.files.images import ImageFile from django.utils.functional import LazyObject from ..files import BaseIKFile @@ -71,6 +72,12 @@ def _generate(self): actual_name = self.storage.save(self.name, content) + # Store the generated file. If we don't do this, the next time the + # "file" attribute is accessed, it will result in a call to the storage + # backend (in ``BaseIKFile._get_file``). Since we already have the + # contents of the file, what would the point of that be? + self.file = File(content) + if actual_name != self.name: get_logger().warning( 'The storage backend %s did not save the file with the' From 906fbbd4639b4706e96188f646fd51bb191a51df Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 02:56:44 -0400 Subject: [PATCH 288/527] Reduce calls to backend Reading from an `ImageCacheFile`, will result in accessing its `file` attribute repeatedly which would result in the `before_access` signal being dispatched, which in turn would result in many unnecessary calls to the image cache backend. With this change, we don't send `before_access` if the file has already been created. Similarly, we don't need to try to generate the image if we know for certain that it's already been generated (because we have a reference to it). --- imagekit/cachefiles/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index ad8359a7..5d58edca 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -56,7 +56,8 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c super(ImageCacheFile, self).__init__(storage=storage) def _require_file(self): - before_access.send(sender=self, file=self) + if not getattr(self, '_file', None): + before_access.send(sender=self, file=self) def generate(self, force=False): """ @@ -64,7 +65,8 @@ def generate(self, force=False): whether the file already exists or not. """ - self.cachefile_backend.generate(self, force) + if force or not getattr(self, '_file', None): + self.cachefile_backend.generate(self, force) def _generate(self): # Generate the file From 6db082bca259c16fdc6219f06738d3a4c251e59c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 03:08:43 -0400 Subject: [PATCH 289/527] Reset content pointer --- imagekit/cachefiles/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 5d58edca..3e67420a 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -74,6 +74,9 @@ def _generate(self): actual_name = self.storage.save(self.name, content) + # We're going to reuse the generated file, so we need to reset the pointer. + content.seek(0) + # Store the generated file. If we don't do this, the next time the # "file" attribute is accessed, it will result in a call to the storage # backend (in ``BaseIKFile._get_file``). Since we already have the From c89b18aa95083f3b867e575380a908ef9bbb358c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 04:39:46 -0400 Subject: [PATCH 290/527] Split before_access into two signals Differentiating between when the generated file content is required and when the generated file is just required to exist gives us more flexibility with strategies. --- docs/caching.rst | 15 ++++++++++---- imagekit/cachefiles/__init__.py | 33 ++++++++++++++++++++++++++----- imagekit/cachefiles/strategies.py | 5 ++++- imagekit/registry.py | 16 +++++++++++---- imagekit/signals.py | 3 ++- tests/models.py | 10 +++++++--- 6 files changed, 64 insertions(+), 18 deletions(-) diff --git a/docs/caching.rst b/docs/caching.rst index 7bf7ea61..00d9ae80 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -35,18 +35,25 @@ Cache File Strategy Each ``ImageCacheFile`` has a cache file strategy, which abstracts away when image is actually generated. It can implement the following four methods: -* ``before_access`` - called by ``ImageCacheFile`` when you access its url, - width, or height attribute. +* ``on_content_required`` - called by ``ImageCacheFile`` when it requires the + contents of the generated image. For example, when you call ``read()`` or + try to access information contained in the file. +* ``on_existence_required`` - called by ``ImageCacheFile`` when it requires the + generated image to exist but may not be concerned with its contents. For + example, when you access its ``url`` or ``path`` attribute. * ``on_source_created`` - called when the source of a spec is created * ``on_source_changed`` - called when the source of a spec is changed * ``on_source_deleted`` - called when the source of a spec is deleted -The default strategy only defines the first of these, as follows: +The default strategy only defines the first two of these, as follows: .. code-block:: python class JustInTime(object): - def before_access(self, file): + def on_content_required(self, file): + file.generate() + + def on_existence_required(self, file): file.generate() diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 3e67420a..806b960a 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -4,7 +4,7 @@ from django.utils.functional import LazyObject from ..files import BaseIKFile from ..registry import generator_registry -from ..signals import before_access +from ..signals import content_required, existence_required from ..utils import get_logger, get_singleton, generate, get_by_qname @@ -57,7 +57,30 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c def _require_file(self): if not getattr(self, '_file', None): - before_access.send(sender=self, file=self) + content_required.send(sender=self, file=self) + self._file = self.storage.open(self.name, 'rb') + + # The ``path`` and ``url`` properties are overridden so as to not call + # ``_require_file``, which is only meant to be called when the file object + # will be directly interacted with (e.g. when using ``read()``). These only + # require the file to exist; they do not need its contents to work. This + # distinction gives the user the flexibility to create a cache file + # strategy that assumes the existence of a file, but can still make the file + # available when its contents are required. + + def _storage_attr(self, attr): + if not getattr(self, '_file', None): + existence_required.send(sender=self, file=self) + fn = getattr(self.storage, attr) + return fn(self.name) + + @property + def path(self): + return self._storage_attr('path') + + @property + def url(http://github.com/self): + return self._storage_attr('url') def generate(self, force=False): """ @@ -101,9 +124,9 @@ def __nonzero__(self): if not self.name: return False - # Dispatch the before_access signal before checking to see if the file - # exists. This gives the strategy a chance to create the file. - before_access.send(sender=self, file=self) + # Dispatch the existence_required signal before checking to see if the + # file exists. This gives the strategy a chance to create the file. + existence_required.send(sender=self, file=self) return self.cachefile_backend.exists(self) diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index 1104de62..af678ba0 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -8,7 +8,10 @@ class JustInTime(object): """ - def before_access(self, file): + def on_existence_required(self, file): + file.generate() + + def on_content_required(self, file): file.generate() diff --git a/imagekit/registry.py b/imagekit/registry.py index a881aa31..d781b062 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,5 +1,6 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import before_access, source_created, source_changed, source_deleted +from .signals import (content_required, existence_required, source_created, + source_changed, source_deleted) from .utils import call_strategy_method @@ -12,7 +13,8 @@ class GeneratorRegistry(object): """ def __init__(self): self._generators = {} - before_access.connect(self.before_access_receiver) + content_required.connect(self.content_required_receiver) + existence_required.connect(self.existence_required_receiver) def register(self, id, generator): registered_generator = self._generators.get(id) @@ -42,13 +44,19 @@ def get(self, id, **kwargs): def get_ids(self): return self._generators.keys() - def before_access_receiver(self, sender, file, **kwargs): + def content_required_receiver(self, sender, file, **kwargs): + self._receive(file, 'on_content_required') + + def existence_required_receiver(self, sender, file, **kwargs): + self._receive(file, 'on_existence_required') + + def _receive(self, file, callback): generator = file.generator # FIXME: I guess this means you can't register functions? if generator.__class__ in self._generators.values(): # Only invoke the strategy method for registered generators. - call_strategy_method(file, 'before_access') + call_strategy_method(file, callback) class SourceGroupRegistry(object): diff --git a/imagekit/signals.py b/imagekit/signals.py index 36c915bd..12a0042f 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -2,7 +2,8 @@ # Generated file signals -before_access = Signal() +content_required = Signal() +existence_required = Signal() # Source group signals source_created = Signal() diff --git a/tests/models.py b/tests/models.py index f1e20c2c..758f2cbf 100644 --- a/tests/models.py +++ b/tests/models.py @@ -29,12 +29,16 @@ class ProcessedImageFieldModel(models.Model): class CountingCacheFileStrategy(object): def __init__(self): - self.before_access_count = 0 + self.on_existence_required_count = 0 + self.on_content_required_count = 0 self.on_source_changed_count = 0 self.on_source_created_count = 0 - def before_access(self, file): - self.before_access_count += 1 + def on_existence_required(self, file): + self.on_existence_required_count += 1 + + def on_content_required(self, file): + self.on_content_required_count += 1 def on_source_changed(self, file): self.on_source_changed_count += 1 From 34739819aa4295b73e665fac931b24d6c5b56c6e Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 10 May 2013 04:43:01 -0400 Subject: [PATCH 291/527] Fix None checks Files can be falsy --- imagekit/cachefiles/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 806b960a..7d8233ae 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -56,7 +56,7 @@ def __init__(self, generator, name=None, storage=None, cachefile_backend=None, c super(ImageCacheFile, self).__init__(storage=storage) def _require_file(self): - if not getattr(self, '_file', None): + if getattr(self, '_file', None) is None: content_required.send(sender=self, file=self) self._file = self.storage.open(self.name, 'rb') @@ -69,7 +69,7 @@ def _require_file(self): # available when its contents are required. def _storage_attr(self, attr): - if not getattr(self, '_file', None): + if getattr(self, '_file', None) is None: existence_required.send(sender=self, file=self) fn = getattr(self.storage, attr) return fn(self.name) @@ -88,7 +88,7 @@ def generate(self, force=False): whether the file already exists or not. """ - if force or not getattr(self, '_file', None): + if force or getattr(self, '_file', None) is None: self.cachefile_backend.generate(self, force) def _generate(self): From 6023e9216ac52314234411a03db5c0f0963256de Mon Sep 17 00:00:00 2001 From: Saul Shanabrook Date: Sat, 11 May 2013 09:12:29 -0300 Subject: [PATCH 292/527] pass in upscale keyword to thumbnail template tag --- imagekit/generatorlibrary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/generatorlibrary.py b/imagekit/generatorlibrary.py index bc5a0f8b..f07e606d 100644 --- a/imagekit/generatorlibrary.py +++ b/imagekit/generatorlibrary.py @@ -4,9 +4,9 @@ class Thumbnail(ImageSpec): - def __init__(self, width=None, height=None, anchor=None, crop=None, **kwargs): + def __init__(self, width=None, height=None, anchor=None, crop=None, upscale=None, **kwargs): self.processors = [ThumbnailProcessor(width, height, anchor=anchor, - crop=crop)] + crop=crop, upscale=upscale)] super(Thumbnail, self).__init__(**kwargs) From 32522114db3c9afc5331a898df3b956b6a3d229a Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 13 May 2013 21:28:41 -0400 Subject: [PATCH 293/527] Improve default cache backend handling --- imagekit/conf.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index dd082e7a..1edad959 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -17,10 +17,21 @@ class ImageKitConf(AppConf): def configure_cache_backend(self, value): if value is None: - if getattr(settings, 'CACHES', None): - value = 'django.core.cache.backends.dummy.DummyCache' if settings.DEBUG else 'default' + try: + from django.core.cache.backends.dummy import DummyCache + except ImportError: + dummy_cache = 'dummy://' else: - value = 'dummy://' if settings.DEBUG else settings.CACHE_BACKEND + dummy_cache = 'django.core.cache.backends.dummy.DummyCache' + + if settings.DEBUG: + value = dummy_cache + else: + value = ( + getattr(settings, 'CACHES', {}).get('default') + or getattr(settings, 'CACHE_BACKEND', None) + or dummy_cache + ) return value def configure_default_file_storage(self, value): From 0d5bfe37517955cca2284735769fe1dffb38ed37 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 20 May 2013 19:18:35 -0400 Subject: [PATCH 294/527] Define NullHandler for Python <= 2.6 Closes #219 --- imagekit/lib.py | 9 +++++++++ imagekit/utils.py | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index 7137e08a..6da2bfb0 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -22,3 +22,12 @@ from cStringIO import StringIO except ImportError: from StringIO import StringIO + +try: + from logging import NullHandler +except ImportError: + from logging import Handler + + class NullHandler(Handler): + def emit(self, record): + pass diff --git a/imagekit/utils.py b/imagekit/utils.py index a0f1e096..188a1114 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -8,6 +8,7 @@ from hashlib import md5 from pilkit.utils import * import re +from .lib import NullHandler bad_memcached_key_chars = re.compile(ur'[\u0000-\u001f\s]+') @@ -82,7 +83,7 @@ def autodiscover(): def get_logger(logger_name='imagekit', add_null_handler=True): logger = logging.getLogger(logger_name) if add_null_handler: - logger.addHandler(logging.NullHandler()) + logger.addHandler(NullHandler()) return logger From 397a79ba56abfcbfb09e49652ea4a0bd89c70edf Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 24 May 2013 23:21:30 -0400 Subject: [PATCH 295/527] Combine source_created and source_changed As discussed in #214, source_created and source_changed didn't really have clear definitions. In truth, their names and separation betray their origins as model receivers in earlier versions. The "source group" abstraction helped us get away from thinking about things exclusively in terms of models, but these remained as an artifact. --- docs/advanced_usage.rst | 5 ++--- docs/caching.rst | 3 +-- imagekit/cachefiles/strategies.py | 5 +---- imagekit/registry.py | 7 +++---- imagekit/signals.py | 3 +-- imagekit/specs/sourcegroups.py | 14 +++++--------- tests/models.py | 10 +++------- tests/test_abstract_models.py | 8 ++++---- 8 files changed, 20 insertions(+), 35 deletions(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 15dfb138..a2559ad4 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -177,7 +177,6 @@ Running the "generateimages" management command would now cause thumbnails to be generated (using the "myapp:profile:avatar_thumbnail" spec) for each of the JPEGs in `/path/to/some/pics`. -Note that, since this source group doesnt send the `source_created` or -`source_changed` signals, the corresponding cache file strategy callbacks -would not be called for them. +Note that, since this source group doesnt send the `source_saved` signal, the +corresponding cache file strategy callbacks would not be called for them. diff --git a/docs/caching.rst b/docs/caching.rst index 00d9ae80..ff336b99 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -41,8 +41,7 @@ image is actually generated. It can implement the following four methods: * ``on_existence_required`` - called by ``ImageCacheFile`` when it requires the generated image to exist but may not be concerned with its contents. For example, when you access its ``url`` or ``path`` attribute. -* ``on_source_created`` - called when the source of a spec is created -* ``on_source_changed`` - called when the source of a spec is changed +* ``on_source_saved`` - called when the source of a spec is saved * ``on_source_deleted`` - called when the source of a spec is deleted The default strategy only defines the first two of these, as follows: diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index af678ba0..fba6a0f0 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -23,10 +23,7 @@ class Optimistic(object): """ - def on_source_created(self, file): - file.generate() - - def on_source_changed(self, file): + def on_source_saved(self, file): file.generate() diff --git a/imagekit/registry.py b/imagekit/registry.py index d781b062..f3633992 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,6 +1,6 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import (content_required, existence_required, source_created, - source_changed, source_deleted) +from .signals import (content_required, existence_required, source_saved, + source_deleted) from .utils import call_strategy_method @@ -70,8 +70,7 @@ class SourceGroupRegistry(object): """ _signals = { - source_created: 'on_source_created', - source_changed: 'on_source_changed', + source_saved: 'on_source_saved', source_deleted: 'on_source_deleted', } diff --git a/imagekit/signals.py b/imagekit/signals.py index 12a0042f..7dc57aea 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -6,6 +6,5 @@ existence_required = Signal() # Source group signals -source_created = Signal() -source_changed = Signal() +source_saved = Signal() source_deleted = Signal() diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 69f2daf6..96ec48e0 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -2,9 +2,8 @@ Source groups are the means by which image spec sources are identified. They have two responsibilities: -1. To dispatch ``source_created``, ``source_changed``, and ``source_deleted`` - signals. (These will be relayed to the corresponding specs' cache file - strategies.) +1. To dispatch ``source_saved``, and ``source_deleted`` signals. (These will be + relayed to the corresponding specs' cache file strategies.) 2. To provide the source files that they represent, via a generator method named ``files()``. (This is used by the generateimages management command for "pre-caching" image files.) @@ -15,7 +14,7 @@ from django.utils.functional import wraps import inspect from ..cachefiles import LazyImageCacheFile -from ..signals import source_created, source_changed, source_deleted +from ..signals import source_saved, source_deleted from ..utils import get_nonabstract_descendants @@ -94,11 +93,8 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): - if created: - self.dispatch_signal(source_created, file, sender, instance, - attname) - elif old_hashes[attname] != new_hashes[attname]: - self.dispatch_signal(source_changed, file, sender, instance, + if created or old_hashes[attname] != new_hashes[attname]: + self.dispatch_signal(source_saved, file, sender, instance, attname) @ik_model_receiver diff --git a/tests/models.py b/tests/models.py index 758f2cbf..5667cad0 100644 --- a/tests/models.py +++ b/tests/models.py @@ -31,8 +31,7 @@ class CountingCacheFileStrategy(object): def __init__(self): self.on_existence_required_count = 0 self.on_content_required_count = 0 - self.on_source_changed_count = 0 - self.on_source_created_count = 0 + self.on_source_saved_count = 0 def on_existence_required(self, file): self.on_existence_required_count += 1 @@ -40,11 +39,8 @@ def on_existence_required(self, file): def on_content_required(self, file): self.on_content_required_count += 1 - def on_source_changed(self, file): - self.on_source_changed_count += 1 - - def on_source_created(self, file): - self.on_source_created_count += 1 + def on_source_saved(self, file): + self.on_source_saved_count += 1 class AbstractImageModel(models.Model): diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py index a3ec7749..4621d593 100644 --- a/tests/test_abstract_models.py +++ b/tests/test_abstract_models.py @@ -1,5 +1,5 @@ from django.core.files import File -from imagekit.signals import source_created +from imagekit.signals import source_saved from imagekit.specs.sourcegroups import ImageFieldSourceGroup from imagekit.utils import get_nonabstract_descendants from nose.tools import eq_ @@ -8,7 +8,7 @@ from .utils import get_image_file -def test_source_created_signal(): +def test_source_saved_signal(): source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') count = [0] @@ -16,10 +16,10 @@ def receiver(sender, *args, **kwargs): if sender is source_group: count[0] += 1 - source_created.connect(receiver, dispatch_uid='test_source_created') + source_saved.connect(receiver, dispatch_uid='test_source_saved') instance = ConcreteImageModel() img = File(get_image_file()) - instance.original_image.save('test_source_created_signal.jpg', img) + instance.original_image.save('test_source_saved_signal.jpg', img) eq_(count[0], 1) From 4ff55724dccc8e44ca283afddad9727ed25bf8d9 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Fri, 24 May 2013 23:46:02 -0400 Subject: [PATCH 296/527] Separate source group tests; signal counting util --- tests/test_abstract_models.py | 22 +--------------------- tests/test_sourcegroups.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 tests/test_sourcegroups.py diff --git a/tests/test_abstract_models.py b/tests/test_abstract_models.py index 4621d593..302fc07e 100644 --- a/tests/test_abstract_models.py +++ b/tests/test_abstract_models.py @@ -1,27 +1,7 @@ -from django.core.files import File -from imagekit.signals import source_saved -from imagekit.specs.sourcegroups import ImageFieldSourceGroup from imagekit.utils import get_nonabstract_descendants from nose.tools import eq_ from . models import (AbstractImageModel, ConcreteImageModel, - ConcreteImageModelSubclass) -from .utils import get_image_file - - -def test_source_saved_signal(): - source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') - count = [0] - - def receiver(sender, *args, **kwargs): - if sender is source_group: - count[0] += 1 - - source_saved.connect(receiver, dispatch_uid='test_source_saved') - instance = ConcreteImageModel() - img = File(get_image_file()) - instance.original_image.save('test_source_saved_signal.jpg', img) - - eq_(count[0], 1) + ConcreteImageModelSubclass) def test_nonabstract_descendants_generator(): diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py new file mode 100644 index 00000000..03fd4671 --- /dev/null +++ b/tests/test_sourcegroups.py @@ -0,0 +1,29 @@ +from django.core.files import File +from imagekit.signals import source_saved +from imagekit.specs.sourcegroups import ImageFieldSourceGroup +from nose.tools import eq_ +from . models import AbstractImageModel, ConcreteImageModel +from .utils import get_image_file + + +def make_counting_receiver(source_group): + def receiver(sender, *args, **kwargs): + if sender is source_group: + receiver.count += 1 + receiver.count = 0 + return receiver + + +def test_abstract_model_signals(): + """ + Source groups created for abstract models must cause signals to be + dispatched on their concrete subclasses. + + """ + source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') + receiver = make_counting_receiver(source_group) + source_saved.connect(receiver) + instance = ConcreteImageModel() + img = File(get_image_file()) + instance.original_image.save('test_source_saved_signal.jpg', img) + eq_(receiver.count, 1) From a6ef72027be6a6fb62b41acaed0340a8d8d91830 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 25 May 2013 00:01:58 -0400 Subject: [PATCH 297/527] Make test less verbose --- tests/test_sourcegroups.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index 03fd4671..a60945ad 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -23,7 +23,5 @@ def test_abstract_model_signals(): source_group = ImageFieldSourceGroup(AbstractImageModel, 'original_image') receiver = make_counting_receiver(source_group) source_saved.connect(receiver) - instance = ConcreteImageModel() - img = File(get_image_file()) - instance.original_image.save('test_source_saved_signal.jpg', img) + ConcreteImageModel.objects.create(original_image=File(get_image_file())) eq_(receiver.count, 1) From c6a0a13c45656ff98984b85a34da91242f32b41c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 25 May 2013 00:02:26 -0400 Subject: [PATCH 298/527] Test that source_saved is dispatched for new instance --- tests/test_sourcegroups.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index a60945ad..f0ffe2a9 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -2,7 +2,7 @@ from imagekit.signals import source_saved from imagekit.specs.sourcegroups import ImageFieldSourceGroup from nose.tools import eq_ -from . models import AbstractImageModel, ConcreteImageModel +from . models import AbstractImageModel, ImageModel, ConcreteImageModel from .utils import get_image_file @@ -14,6 +14,19 @@ def receiver(sender, *args, **kwargs): return receiver +def test_source_saved_signal(): + """ + Creating a new instance with an image causes the source_saved signal to be + dispatched. + + """ + source_group = ImageFieldSourceGroup(ImageModel, 'image') + receiver = make_counting_receiver(source_group) + source_saved.connect(receiver) + ImageModel.objects.create(image=File(get_image_file())) + eq_(receiver.count, 1) + + def test_abstract_model_signals(): """ Source groups created for abstract models must cause signals to be From 404fed58eca018b74bc846cbf4f71a03f93f4712 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 25 May 2013 00:07:58 -0400 Subject: [PATCH 299/527] Add failing test for source_save signal w/o source This is like the test contributed by @saulshanabrook in #214, but catches the bug closer to its source. (A more unit-y unit test.) --- tests/test_sourcegroups.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index f0ffe2a9..12eed3b1 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -27,6 +27,21 @@ def test_source_saved_signal(): eq_(receiver.count, 1) +def test_no_source_saved_signal(): + """ + Creating a new instance without an image shouldn't cause the source_saved + signal to be dispatched. + + https://github.com/jdriscoll/django-imagekit/issues/214 + + """ + source_group = ImageFieldSourceGroup(ImageModel, 'image') + receiver = make_counting_receiver(source_group) + source_saved.connect(receiver) + ImageModel.objects.create() + eq_(receiver.count, 0) + + def test_abstract_model_signals(): """ Source groups created for abstract models must cause signals to be From 535e68aea6f4a2d63bb234c53a32728ead75a1cc Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 25 May 2013 00:19:14 -0400 Subject: [PATCH 300/527] Don't send source_saved when no source Fixes #214 and the failing test from 404fed5 --- imagekit/specs/sourcegroups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 96ec48e0..2236cb24 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -93,7 +93,7 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) for attname, file in self.get_field_dict(instance).items(): - if created or old_hashes[attname] != new_hashes[attname]: + if file and old_hashes[attname] != new_hashes[attname]: self.dispatch_signal(source_saved, file, sender, instance, attname) From f9d91c7c4d7b843ec5e26979f884b08d5d70e3ff Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 25 May 2013 00:50:59 -0400 Subject: [PATCH 301/527] Remove source_deleted signal ...for now. Eventually, we will want a signal that tells us when sources are no longer used, however that isn't just limited to when they're deleted! This new signal should also be dispatched, for example, when a source image field is set to `None`. Since none of the built-in strategies are currently using the source_deleted signal, I've decided to remove it until we have a more complete solution. --- docs/advanced_usage.rst | 2 +- docs/caching.rst | 3 +-- imagekit/registry.py | 4 +--- imagekit/signals.py | 1 - imagekit/specs/sourcegroups.py | 14 ++++---------- 5 files changed, 7 insertions(+), 17 deletions(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index a2559ad4..6db20715 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -122,7 +122,7 @@ The answer is that, when you define an ImageSpecField, ImageKit automatically creates and registers an object called a *source group*. Source groups are responsible for two things: -1. They dispatch signals when a source is created, changed, or deleted, and +1. They dispatch signals when a source is saved, and 2. They expose a generator method that enumerates source files. When these objects are registered (using ``imagekit.register.source_group()``), diff --git a/docs/caching.rst b/docs/caching.rst index ff336b99..e6ab26d8 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -33,7 +33,7 @@ Cache File Strategy ------------------- Each ``ImageCacheFile`` has a cache file strategy, which abstracts away when -image is actually generated. It can implement the following four methods: +image is actually generated. It can implement the following three methods: * ``on_content_required`` - called by ``ImageCacheFile`` when it requires the contents of the generated image. For example, when you call ``read()`` or @@ -42,7 +42,6 @@ image is actually generated. It can implement the following four methods: generated image to exist but may not be concerned with its contents. For example, when you access its ``url`` or ``path`` attribute. * ``on_source_saved`` - called when the source of a spec is saved -* ``on_source_deleted`` - called when the source of a spec is deleted The default strategy only defines the first two of these, as follows: diff --git a/imagekit/registry.py b/imagekit/registry.py index f3633992..f1aba898 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,6 +1,5 @@ from .exceptions import AlreadyRegistered, NotRegistered -from .signals import (content_required, existence_required, source_saved, - source_deleted) +from .signals import content_required, existence_required, source_saved from .utils import call_strategy_method @@ -71,7 +70,6 @@ class SourceGroupRegistry(object): """ _signals = { source_saved: 'on_source_saved', - source_deleted: 'on_source_deleted', } def __init__(self): diff --git a/imagekit/signals.py b/imagekit/signals.py index 7dc57aea..4bca574c 100644 --- a/imagekit/signals.py +++ b/imagekit/signals.py @@ -7,4 +7,3 @@ # Source group signals source_saved = Signal() -source_deleted = Signal() diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 2236cb24..dd804dc7 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -2,19 +2,19 @@ Source groups are the means by which image spec sources are identified. They have two responsibilities: -1. To dispatch ``source_saved``, and ``source_deleted`` signals. (These will be - relayed to the corresponding specs' cache file strategies.) +1. To dispatch ``source_saved`` signals. (These will be relayed to the + corresponding specs' cache file strategies.) 2. To provide the source files that they represent, via a generator method named ``files()``. (This is used by the generateimages management command for "pre-caching" image files.) """ -from django.db.models.signals import post_init, post_save, post_delete +from django.db.models.signals import post_init, post_save from django.utils.functional import wraps import inspect from ..cachefiles import LazyImageCacheFile -from ..signals import source_saved, source_deleted +from ..signals import source_saved from ..utils import get_nonabstract_descendants @@ -57,7 +57,6 @@ def __init__(self): uid = 'ik_spec_field_receivers' post_init.connect(self.post_init_receiver, dispatch_uid=uid) post_save.connect(self.post_save_receiver, dispatch_uid=uid) - post_delete.connect(self.post_delete_receiver, dispatch_uid=uid) def add(self, source_group): self._source_groups.append(source_group) @@ -97,11 +96,6 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** self.dispatch_signal(source_saved, file, sender, instance, attname) - @ik_model_receiver - def post_delete_receiver(self, sender, instance=None, **kwargs): - for attname, file in self.get_field_dict(instance).items(): - self.dispatch_signal(source_deleted, file, sender, instance, attname) - @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): self.update_source_hashes(instance) From 761dcd20ae70974d35fd2ac6f383e363e85231d2 Mon Sep 17 00:00:00 2001 From: Ilya Semenov Date: Sat, 25 May 2013 16:45:40 +0700 Subject: [PATCH 302/527] Fixed thumbnail template tag treating provided sizes as strings, not integers --- imagekit/templatetags/imagekit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 7553a2f9..fdf1b148 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -28,7 +28,7 @@ def parse_dimensions(dimensions): will be None for that value. """ - width, height = [d.strip() or None for d in dimensions.split('x')] + width, height = [d.strip() and int(d) or None for d in dimensions.split('x')] return dict(width=width, height=height) From 0e0240085fae8c3bcde3b8c4d08a5d32c03143a2 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Thu, 30 May 2013 00:26:34 -0700 Subject: [PATCH 303/527] Bump the version number to 3.0.0. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 596bb6c1..e7813dd6 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0b1' +__version__ = '3.0.0' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From af73a939536413b8d9caebcff0c8f94c11867663 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 3 Jun 2013 10:31:57 -0300 Subject: [PATCH 304/527] Add import to example Closes #224 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index c2b60a77..ae65e8a5 100644 --- a/README.rst +++ b/README.rst @@ -177,7 +177,7 @@ to register it. .. code-block:: python - from imagekit import ImageSpec + from imagekit import ImageSpec, register from imagekit.processors import ResizeToFill class Thumbnail(ImageSpec): From 02cd1bf7ffd3066261cd969ecfcf339beb623629 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Mon, 3 Jun 2013 12:50:20 -0700 Subject: [PATCH 305/527] I, for one, welcome our new @matthewwithanm overlords. --- AUTHORS | 2 +- CONTRIBUTING.rst | 2 +- README.rst | 12 ++++++------ imagekit/models/fields/__init__.py | 2 +- imagekit/specs/sourcegroups.py | 2 +- setup.py | 6 +++--- tests/test_sourcegroups.py | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/AUTHORS b/AUTHORS index 34c4c8de..255827bf 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,8 +6,8 @@ HZDG_. Maintainers ----------- -* `Bryan Veloso`_ * `Matthew Tretter`_ +* `Bryan Veloso`_ * `Chris Drackett`_ * `Greg Newman`_ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index e36fd1cb..b9f2de26 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -21,4 +21,4 @@ __ http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html __ https://groups.google.com/forum/#!forum/django-imagekit __ irc://irc.freenode.net/imagekit .. _nose: https://nose.readthedocs.org/en/latest/ -__ https://github.com/jdriscoll/django-imagekit/tree/develop/tests +__ https://github.com/matthewwithanm/django-imagekit/tree/develop/tests diff --git a/README.rst b/README.rst index ae65e8a5..53e8781a 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ |Build Status|_ -.. |Build Status| image:: https://travis-ci.org/jdriscoll/django-imagekit.png?branch=develop -.. _Build Status: https://travis-ci.org/jdriscoll/django-imagekit +.. |Build Status| image:: https://travis-ci.org/matthewwithanm/django-imagekit.png?branch=develop +.. _Build Status: https://travis-ci.org/matthewwithanm/django-imagekit ImageKit is a Django app for processing images. Need a thumbnail? A black-and-white version of a user-uploaded image? ImageKit will make them for @@ -371,7 +371,7 @@ it in your spec's ``processors`` list: options = {'quality': 60} Note that when you import a processor from ``imagekit.processors``, imagekit -in turn imports the processor from `PILKit`_. So if you are looking for +in turn imports the processor from `PILKit`_. So if you are looking for available processors, look at PILKit. .. _`PILKit`: https://github.com/matthewwithanm/pilkit @@ -414,7 +414,7 @@ of generator ids in order to generate images selectively. Community ========= -Please use `the GitHub issue tracker `_ +Please use `the GitHub issue tracker `_ to report bugs with django-imagekit. `A mailing list `_ also exists to discuss the project and ask questions, as well as the official `#imagekit `_ channel on Freenode. @@ -436,5 +436,5 @@ Check out our `contributing guidelines`__ for more information about pitching in with ImageKit. -__ https://github.com/jdriscoll/django-imagekit/issues?labels=contributor-friendly&state=open -__ https://github.com/jdriscoll/django-imagekit/blob/develop/CONTRIBUTING.rst +__ https://github.com/matthewwithanm/django-imagekit/issues?labels=contributor-friendly&state=open +__ https://github.com/matthewwithanm/django-imagekit/blob/develop/CONTRIBUTING.rst diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 3f1a2f62..91c62523 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -39,7 +39,7 @@ def __init__(self, processors=None, format=None, options=None, cachefile_strategy=cachefile_strategy, spec=spec, spec_id=id) - # TODO: Allow callable for source. See https://github.com/jdriscoll/django-imagekit/issues/158#issuecomment-10921664 + # TODO: Allow callable for source. See https://github.com/matthewwithanm/django-imagekit/issues/158#issuecomment-10921664 self.source = source def contribute_to_class(self, cls, name): diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index dd804dc7..2008f593 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -47,7 +47,7 @@ class ModelSignalRouter(object): ``ImageFieldSourceGroup``s. This class encapsulates that functionality. Related: - https://github.com/jdriscoll/django-imagekit/issues/126 + https://github.com/matthewwithanm/django-imagekit/issues/126 https://code.djangoproject.com/ticket/9318 """ diff --git a/setup.py b/setup.py index 393c0199..da959a01 100644 --- a/setup.py +++ b/setup.py @@ -31,12 +31,12 @@ version=pkgmeta['__version__'], description='Automated image processing for Django models.', long_description=read(os.path.join(os.path.dirname(__file__), 'README.rst')), - author='Justin Driscoll', - author_email='justin@driscolldev.com', + author='Matthew Tretter', + author_email='m@tthewwithanm.com', maintainer='Bryan Veloso', maintainer_email='bryan@revyver.com', license='BSD', - url='http://github.com/jdriscoll/django-imagekit/', + url='http://github.com/matthewwithanm/django-imagekit/', packages=find_packages(), zip_safe=False, include_package_data=True, diff --git a/tests/test_sourcegroups.py b/tests/test_sourcegroups.py index 12eed3b1..c69b11f3 100644 --- a/tests/test_sourcegroups.py +++ b/tests/test_sourcegroups.py @@ -32,7 +32,7 @@ def test_no_source_saved_signal(): Creating a new instance without an image shouldn't cause the source_saved signal to be dispatched. - https://github.com/jdriscoll/django-imagekit/issues/214 + https://github.com/matthewwithanm/django-imagekit/issues/214 """ source_group = ImageFieldSourceGroup(ImageModel, 'image') From d3882c34b29c651e0fb8611ac0141e075e5235f9 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Jun 2013 21:36:31 -0400 Subject: [PATCH 306/527] Update installation directions; closes #223 --- README.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/README.rst b/README.rst index 53e8781a..8a30efdd 100644 --- a/README.rst +++ b/README.rst @@ -21,7 +21,6 @@ Installation 1. Install `PIL`_ or `Pillow`_. (If you're using an ``ImageField`` in Django, you should have already done this.) 2. ``pip install django-imagekit`` - (or clone the source and put the imagekit module on your path) 3. Add ``'imagekit'`` to your ``INSTALLED_APPS`` list in your project's settings.py .. note:: If you've never seen Pillow before, it considers itself a From 6582794408af457d65c426e37c72fa6ec6dd4463 Mon Sep 17 00:00:00 2001 From: Jacob Magnusson Date: Tue, 14 May 2013 10:44:08 +0200 Subject: [PATCH 307/527] Remove unused imports --- tests/test_cachefiles.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 957b1320..3cd6af6f 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -3,8 +3,6 @@ from imagekit.cachefiles import ImageCacheFile from imagekit.cachefiles.backends import Simple from nose.tools import raises, eq_ -import random -import string from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, DummyAsyncCacheFileBackend, get_unique_image_file) From 654867c3cf46ca8dcf21666dcb1d968d621eda0d Mon Sep 17 00:00:00 2001 From: Jacob Magnusson Date: Mon, 20 May 2013 11:22:59 +0200 Subject: [PATCH 308/527] PEP 3110 compat --- imagekit/management/commands/generateimages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 099fe3d0..444440a0 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -27,7 +27,7 @@ def handle(self, *args, **options): try: # TODO: Allow other validation actions through command option file.generate() - except Exception, err: + except Exception as err: # TODO: How should we handle failures? Don't want to error, but should call it out more than this. self.stdout.write(' FAILED: %s\n' % err) From 3001069254a320fb3a2fa519dc61e14b329cc00f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Jun 2013 23:34:26 -0400 Subject: [PATCH 309/527] Test stringification of LazyImageCacheFiles --- tests/test_cachefiles.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 3cd6af6f..4338a822 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,11 +1,12 @@ from django.conf import settings from hashlib import md5 -from imagekit.cachefiles import ImageCacheFile +from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple from nose.tools import raises, eq_ from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, - DummyAsyncCacheFileBackend, get_unique_image_file) + DummyAsyncCacheFileBackend, get_unique_image_file, + get_image_file) def test_no_source_falsiness(): @@ -73,3 +74,15 @@ def __init__(self, name): settings.IMAGEKIT_CACHE_PREFIX, '1' * (200 - len(':') - 32 - len(settings.IMAGEKIT_CACHE_PREFIX)), md5('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename)).hexdigest())) + + +def test_lazyfile_stringification(): + file = LazyImageCacheFile('testspec', source=None) + eq_(str(file), '') + eq_(repr(file), '') + + source_file = get_image_file() + file = LazyImageCacheFile('testspec', source=source_file) + file.name = 'a.jpg' + eq_(str(file), 'a.jpg') + eq_(repr(file), '') From 01a6c555a159fa4a88bba58bd1fb5b5721ec03e1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 4 Jun 2013 23:33:09 -0400 Subject: [PATCH 310/527] Fix LazyImageCacheFile.__repr__ and __str__ Using SimpleLazyObject also lets us clean things up a bit. Closes #218 --- imagekit/cachefiles/__init__.py | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 7d8233ae..2c602ffc 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -1,7 +1,7 @@ from django.conf import settings from django.core.files import File from django.core.files.images import ImageFile -from django.utils.functional import LazyObject +from django.utils.functional import SimpleLazyObject from ..files import BaseIKFile from ..registry import generator_registry from ..signals import content_required, existence_required @@ -130,27 +130,12 @@ def __nonzero__(self): return self.cachefile_backend.exists(self) -class LazyImageCacheFile(LazyObject): +class LazyImageCacheFile(SimpleLazyObject): def __init__(self, generator_id, *args, **kwargs): - super(LazyImageCacheFile, self).__init__() - def setup(): generator = generator_registry.get(generator_id, *args, **kwargs) - self._wrapped = ImageCacheFile(generator) - - self.__dict__['_setup'] = setup + return ImageCacheFile(generator) + super(LazyImageCacheFile, self).__init__(setup) def __repr__(self): - if self._wrapped is None: - self._setup() - return '<%s: %s>' % (self.__class__.__name__, self or 'None') - - def __str__(self): - if self._wrapped is None: - self._setup() - return str(self._wrapped) - - def __unicode__(self): - if self._wrapped is None: - self._setup() - return unicode(self._wrapped) + return '<%s: %s>' % (self.__class__.__name__, str(self) or 'None') From bb7e9e58917a54e0982d4d343ed14895b3e9871c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Mon, 10 Jun 2013 18:33:22 -0400 Subject: [PATCH 311/527] Fix cache backend fallback Closes #225 Closes #226 --- imagekit/conf.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 1edad959..2900da1f 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -24,14 +24,19 @@ def configure_cache_backend(self, value): else: dummy_cache = 'django.core.cache.backends.dummy.DummyCache' + # DEFAULT_CACHE_ALIAS doesn't exist in Django<=1.2 + try: + from django.core.cache import DEFAULT_CACHE_ALIAS as default_cache_alias + except ImportError: + default_cache_alias = 'default' + if settings.DEBUG: value = dummy_cache + elif default_cache_alias in getattr(settings, 'CACHES', {}): + value = default_cache_alias else: - value = ( - getattr(settings, 'CACHES', {}).get('default') - or getattr(settings, 'CACHE_BACKEND', None) - or dummy_cache - ) + value = getattr(settings, 'CACHE_BACKEND', None) or dummy_cache + return value def configure_default_file_storage(self, value): From 90e9d314a61e7b95c317bba288d2fc0ac77b50ca Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Tue, 11 Jun 2013 14:08:23 -0700 Subject: [PATCH 312/527] Bump version to 3.0.1. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index e7813dd6..feb0225d 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0.0' +__version__ = '3.0.1' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From ada883c99f6e76ac17422d41fa0c62f897f2401c Mon Sep 17 00:00:00 2001 From: Rich Leland Date: Thu, 13 Jun 2013 14:10:23 -0400 Subject: [PATCH 313/527] Fixed name of spec id attr --- docs/advanced_usage.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst index 6db20715..bb635e76 100644 --- a/docs/advanced_usage.rst +++ b/docs/advanced_usage.rst @@ -47,7 +47,7 @@ for creating an ``ImageSpec``, registering it, and associating it with an class Profile(models.Model): avatar = models.ImageField(upload_to='avatars') avatar_thumbnail = ImageSpecField(source='avatar', - spec_id='myapp:profile:avatar_thumbnail') + id='myapp:profile:avatar_thumbnail') Obviously, the shorthand version is a lot, well…shorter. So why would you ever want to go through the trouble of using the long form? The answer is that the @@ -97,7 +97,7 @@ for getting this information. class Profile(models.Model): avatar = models.ImageField(upload_to='avatars') avatar_thumbnail = ImageSpecField(source='avatar', - spec_id='myapp:profile:avatar_thumbnail') + id='myapp:profile:avatar_thumbnail') thumbnail_width = models.PositiveIntegerField() thumbnail_height = models.PositiveIntegerField() From 637af709219ed448639861542a2fb1ce0f565454 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 20 Jun 2013 09:17:12 -0400 Subject: [PATCH 314/527] Don't include cache in serialization of backend Fixes #227 --- imagekit/cachefiles/backends.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 18c8e709..f4c9c369 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -1,4 +1,5 @@ from ..utils import get_singleton, sanitize_cache_key +from copy import copy from django.core.cache import get_cache from django.core.exceptions import ImproperlyConfigured @@ -76,6 +77,13 @@ def set_state(self, file, state): else: self.cache.set(key, state) + def __getstate__(self): + state = copy(self.__dict__) + # Don't include the cache when pickling. It'll be reconstituted based + # on the settings. + state.pop('_cache', None) + return state + def exists(self, file): return self.get_state(file) is CacheFileState.EXISTS From db6cfcb6ce7e6465b60d6ca5de6c703ae50892a9 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 13 Jul 2013 16:38:49 -0400 Subject: [PATCH 315/527] Add (failing) test for #234 --- tests/test_serialization.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_serialization.py b/tests/test_serialization.py index cd7b6d72..85ab1574 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -11,3 +11,15 @@ def test_imagespecfield(): instance = create_photo('pickletest2.jpg') thumbnail = pickleback(instance.thumbnail) thumbnail.generate() + + +def test_circular_ref(): + """ + A model instance with a spec field in its dict shouldn't raise a KeyError. + + This corresponds to #234 + + """ + instance = create_photo('pickletest3.jpg') + instance.thumbnail # Cause thumbnail to be added to instance's __dict__ + pickleback(instance) From 3c04cb852ffaef42255beeb5eec7749bb50d03f7 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 13 Jul 2013 17:12:55 -0400 Subject: [PATCH 316/527] Don't require source in __setstate__; fixes #234 --- imagekit/specs/__init__.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index aaa40a65..18f49586 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -93,25 +93,41 @@ def cachefile_name(self): fn = get_by_qname(settings.IMAGEKIT_SPEC_CACHEFILE_NAMER, 'namer') return fn(self) + @property + def source(self): + src = getattr(self, '_source', None) + if not src: + field_data = getattr(self, '_field_data', None) + if field_data: + src = self._source = getattr(field_data['instance'], field_data['attname']) + del self._field_data + return src + + @source.setter + def source(self, value): + self._source = value + def __getstate__(self): state = self.__dict__ # Unpickled ImageFieldFiles won't work (they're missing a storage # object). Since they're such a common use case, we special case them. + # Unfortunately, this also requires us to add the source getter to + # lazily retrieve the source on the reconstructed object; simply trying + # to look up the source in ``__setstate__`` would require us to get the + # model instance but, if ``__setstate__`` was called as part of + # deserializing that model, the model wouldn't be fully reconstructed + # yet, preventing us from accessing the source field. + # (This is issue #234.) if isinstance(self.source, ImageFieldFile): field = getattr(self.source, 'field') state['_field_data'] = { 'instance': getattr(self.source, 'instance', None), 'attname': getattr(field, 'name', None), } + state.pop('_source', None) return state - def __setstate__(self, state): - field_data = state.pop('_field_data', None) - self.__dict__ = state - if field_data: - self.source = getattr(field_data['instance'], field_data['attname']) - def get_hash(self): return hashers.pickle([ self.source.name, From 14939faef613bd42ff2550deea37a894f38647d1 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 13 Jul 2013 17:13:58 -0400 Subject: [PATCH 317/527] Don't mutate __dict__ --- imagekit/specs/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 18f49586..bc331243 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -1,3 +1,4 @@ +from copy import copy from django.conf import settings from django.db.models.fields.files import ImageFieldFile from ..cachefiles.backends import get_default_cachefile_backend @@ -108,7 +109,7 @@ def source(self, value): self._source = value def __getstate__(self): - state = self.__dict__ + state = copy(self.__dict__) # Unpickled ImageFieldFiles won't work (they're missing a storage # object). Since they're such a common use case, we special case them. From a0c7b3f27477897eb1cfb369dd2ddc420ebc1085 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Jul 2013 20:40:48 -0400 Subject: [PATCH 318/527] Use == for comparison --- imagekit/cachefiles/backends.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index f4c9c369..51e5b73e 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -72,7 +72,7 @@ def get_state(self, file): def set_state(self, file, state): key = self.get_key(file) - if state is CacheFileState.DOES_NOT_EXIST: + if state == CacheFileState.DOES_NOT_EXIST: self.cache.set(key, state, self.existence_check_timeout) else: self.cache.set(key, state) @@ -85,13 +85,13 @@ def __getstate__(self): return state def exists(self, file): - return self.get_state(file) is CacheFileState.EXISTS + return self.get_state(file) == CacheFileState.EXISTS def generate(self, file, force=False): raise NotImplementedError def generate_now(self, file, force=False): - if force or self.get_state(file) is CacheFileState.DOES_NOT_EXIST: + if force or self.get_state(file) == CacheFileState.DOES_NOT_EXIST: file._generate() self.set_state(file, CacheFileState.EXISTS) From 34446260842e2a0e0c5185114a7bac2be23963c6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Tue, 16 Jul 2013 21:02:48 -0400 Subject: [PATCH 319/527] Remove PENDING state Re: #227 --- imagekit/cachefiles/backends.py | 18 ++++++++++++------ tests/utils.py | 5 ++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 51e5b73e..b1274307 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -6,7 +6,7 @@ class CacheFileState(object): EXISTS = 'exists' - PENDING = 'pending' + GENERATING = 'generating' DOES_NOT_EXIST = 'does_not_exist' @@ -61,10 +61,10 @@ def get_key(self, file): return sanitize_cache_key('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, file.name)) - def get_state(self, file): + def get_state(self, file, check_if_unknown=True): key = self.get_key(file) state = self.cache.get(key) - if state is None: + if state is None and check_if_unknown: exists = self._exists(file) state = CacheFileState.EXISTS if exists else CacheFileState.DOES_NOT_EXIST self.set_state(file, state) @@ -91,7 +91,8 @@ def generate(self, file, force=False): raise NotImplementedError def generate_now(self, file, force=False): - if force or self.get_state(file) == CacheFileState.DOES_NOT_EXIST: + if force or self.get_state(file) not in (CacheFileState.GENERATING, CacheFileState.EXISTS): + self.set_state(file, CacheFileState.GENERATING) file._generate() self.set_state(file, CacheFileState.EXISTS) @@ -137,5 +138,10 @@ def __init__(self, *args, **kwargs): super(Async, self).__init__(*args, **kwargs) def generate(self, file, force=False): - self.set_state(file, CacheFileState.PENDING) - _generate_file.delay(self, file, force=force) + # Schedule the file for generation, unless we know for sure we don't + # need to. If an already-generated file sneaks through, that's okay; + # ``generate_now`` will catch it. We just want to make sure we don't + # schedule anything we know is unnecessary--but we also don't want to + # force a costly existence check. + if self.get_state(file, check_if_unknown=False) not in (CacheFileState.GENERATING, CacheFileState.EXISTS): + _generate_file.delay(self, file, force=force) diff --git a/tests/utils.py b/tests/utils.py index 717442a3..5a9f1c5c 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -74,9 +74,8 @@ def assert_file_is_truthy(file): class DummyAsyncCacheFileBackend(Simple): """ - A cache file backend meant to simulate async generation (by marking the - file as pending but never actually creating it). + A cache file backend meant to simulate async generation. """ def generate(self, file, force=False): - self.set_state(file, CacheFileState.PENDING) + pass From cae66779947ff18aad382f1799f55081b506cc06 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Wed, 17 Jul 2013 11:44:31 -0700 Subject: [PATCH 320/527] Bump to 3.0.2. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index feb0225d..9a0434bd 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0.1' +__version__ = '3.0.2' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 05ec0c1b33f469c9471789a5996ad9e14b370e01 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Wed, 17 Jul 2013 11:45:42 -0700 Subject: [PATCH 321/527] Removing the changelog. Changelogs are hard. --- README.rst | 3 +- docs/changelog.rst | 142 --------------------------------------------- docs/index.rst | 1 - 3 files changed, 1 insertion(+), 145 deletions(-) delete mode 100644 docs/changelog.rst diff --git a/README.rst b/README.rst index 8a30efdd..bdfed793 100644 --- a/README.rst +++ b/README.rst @@ -9,10 +9,9 @@ you. If you need to programatically generate one image from another, you need ImageKit. **For the complete documentation on the latest stable version of ImageKit, see** -`ImageKit on RTD`_. Our `changelog is also available`_. +`ImageKit on RTD`_. .. _`ImageKit on RTD`: http://django-imagekit.readthedocs.org -.. _`changelog is also available`: http://django-imagekit.readthedocs.org/en/latest/changelog.html Installation diff --git a/docs/changelog.rst b/docs/changelog.rst deleted file mode 100644 index 072d8e17..00000000 --- a/docs/changelog.rst +++ /dev/null @@ -1,142 +0,0 @@ -Changelog -========= - -v2.0.2 ------- - -- Fixed the pickling of ImageSpecFieldFile. -- Signals are now connected without specifying the class and non-IK models - are filitered out in the receivers. This is necessary beacuse of a bug - with how Django handles abstract models. -- Fixed a `ZeroDivisionError` in the Reflection processor. -- `cStringIO` is now used if it's available. -- Reflections on images now use RGBA instead of RGB. - -v2.0.1 ------- - -- Fixed a file descriptor leak in the `utils.quiet()` context manager. - - -v2.0.0 ------- - -- Added the concept of image cache backends. Image cache backends assume - control of validating and invalidating the cached images from `ImageSpec` in - versions past. The default backend maintins the current behavior: invalidating - an image deletes it, while validating checks whether the file exists and - creates the file if it doesn't. One can create custom image cache backends to - control how their images are cached (e.g., Celery, etc.). - - ImageKit ships with three built-in backends: - - - ``imagekit.imagecache.PessimisticImageCacheBackend`` - A very safe image - cache backend. Guarantees that files will always be available, but at the - cost of hitting the storage backend. - - ``imagekit.imagecache.NonValidatingImageCacheBackend`` - A backend that is - super optimistic about the existence of spec files. It will hit your file - storage much less frequently than the pessimistic backend, but it is - technically possible for a cache file to be missing after validation. - - ``imagekit.imagecache.celery.CeleryImageCacheBackend`` - A pessimistic cache - state backend that uses celery to generate its spec images. Like - ``PessimisticCacheStateBackend``, this one checks to see if the file - exists on validation, so the storage is hit fairly frequently, but an - image is guaranteed to exist. However, while validation guarantees the - existence of *an* image, it does not necessarily guarantee that you will - get the correct image, as the spec may be pending regeneration. In other - words, while there are ``generate`` tasks in the queue, it is possible to - get a stale spec image. The tradeoff is that calling ``invalidate()`` - won't block to interact with file storage. - -- Some of the processors have been renamed and several new ones have been added: - - - ``imagekit.processors.ResizeToFill`` - (previously - ``imagekit.processors.resize.Crop``) Scales the image to fill the provided - dimensions and then trims away the excess. - - ``imagekit.processors.ResizeToFit`` - (previously - ``imagekit.processors.resize.Fit``) Scale to fit the provided dimensions. - - ``imagekit.processors.SmartResize`` - Like ``ResizeToFill``, but crops using - entroy (``SmartCrop``) instead of an anchor argument. - - ``imagekit.processors.BasicCrop`` - Crop using provided box. - - ``imagekit.processors.SmartCrop`` - (previously - ``imagekit.processors.resize.SmartCrop``) Crop to provided size, trimming - based on entropy. - - ``imagekit.processors.TrimBorderColor`` - Trim the specified color from the - specified sides. - - ``imagekit.processors.AddBorder`` - Add a border of specific color and - thickness to an image. - - ``imagekit.processors.Resize`` - Scale to the provided dimensions (can distort). - - ``imagekit.processors.ResizeToCover`` - Scale to the smallest size that will - cover the specified dimensions. Used internally by ``Fill`` and - ``SmartFill``. - - ``imagekit.processors.ResizeCanvas`` - Takes an image an resizes the canvas, - using a specific background color if the new size is larger than the current - image. - -- ``mat_color`` has been added as an arguemnt to ``ResizeToFit``. If set, the - the target image size will be enforced and the specified color will be - used as background color to pad the image. - -- We now use `Tox`_ to automate testing. - -.. _`Tox`: http://pypi.python.org/pypi/tox - - -v1.1.0 ------- - -- A ``SmartCrop`` resize processor was added. This allows an image to be - cropped based on the amount of entropy in the target image's histogram. - -- The ``quality`` argument was removed in favor of an ``options`` dictionary. - This is a more general solution which grants access to PIL's format-specific - options (including "quality", "progressive", and "optimize" for JPEGs). - -- The ``TrimColor`` processor was renamed to ``TrimBorderColor``. - -- The private ``_Resize`` class has been removed. - - -v1.0.3 ------- - -- ``ImageSpec._create()`` was renamed ``ImageSpec.generate()`` and is now - available in the public API. - -- Added an ``AutoConvert`` processor to encapsulate the transparency - handling logic. - -- Refactored transparency handling to be smarter, handling a lot more of - the situations in which one would convert to or from formats that support - transparency. - -- Fixed PIL zeroing out files when write mode is enabled. - - -v1.0.2 ------- - -- Added this changelog. - -- Enhanced extension detection, format detection, and conversion between the - two. This eliminates the reliance on an image being loaded into memory - beforehand in order to detect said image's extension. - -- Fixed a regression from the 0.4.x series in which ImageKit was unable to - convert a PNG file in ``P`` or "palette" mode to JPEG. - - -v1.0.1 ------- - -- Minor fixes related to the rendering of ``README.rst`` as a reStructured - text file. - -- Fixed the included admin template not being found when ImageKit was and - the packaging of the included admin templates. - - -v1.0 ----- - -- Initial release of the *new* field-based ImageKit API. diff --git a/docs/index.rst b/docs/index.rst index 9773f7f1..192ace0d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,5 +21,4 @@ Indices and tables configuration advanced_usage caching - changelog upgrading From e36290b4eef1faaf6ad864d3493df1458ef96fbb Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 17 Jul 2013 16:09:02 -0400 Subject: [PATCH 322/527] Woops. It uses the cache if DEBUG is False. --- docs/caching.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/caching.rst b/docs/caching.rst index e6ab26d8..b482f1f0 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -103,7 +103,7 @@ Caching Data About Generated Files The easiest, and most significant improvement you can make to improve the performance of your site is to have ImageKit cache the state of your generated files. The default cache file backend will already do this (if ``DEBUG`` is -``True``), using your default Django cache backend, but you can make it way +``False``), using your default Django cache backend, but you can make it way better by setting ``IMAGEKIT_CACHE_BACKEND``. Generally, once a file is generated, you will never be removing it; therefore, if you can, you should set ``IMAGEKIT_CACHE_BACKEND`` to a cache backend that will cache forever. From 3be774bbf63a59e31285b930f700749c727c478c Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Mon, 22 Jul 2013 10:01:20 -0700 Subject: [PATCH 323/527] Bump to 3.0.3. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 9a0434bd..19516207 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0.2' +__version__ = '3.0.3' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From bc8fdd7ada6b443530cc632305a04dd53abe9476 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sat, 27 Jul 2013 20:50:16 -0400 Subject: [PATCH 324/527] Run tests with Django 1.5 --- tox.ini | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index c7c54cfd..46ca387b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,16 @@ [tox] envlist = - py27-django14, py27-django13, py27-django12, - py26-django14, py26-django13, py26-django12 + py27-django15, py27-django14, py27-django13, py27-django12, + py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test +[testenv:py27-django15] +basepython = python2.7 +deps = + Django>=1.5,<1.6 + [testenv:py27-django14] basepython = python2.7 deps = @@ -21,6 +26,11 @@ basepython = python2.7 deps = Django>=1.2,<1.3 +[testenv:py26-django15] +basepython = python2.6 +deps = + Django>=1.5,<1.6 + [testenv:py26-django14] basepython = python2.6 deps = From 1a33c2be512871d4dada6d28f3e4b7ffb3695cec Mon Sep 17 00:00:00 2001 From: nex2hex Date: Tue, 13 Aug 2013 18:52:21 +0600 Subject: [PATCH 325/527] Update fields.py Don't overwrite existing image when form saved --- imagekit/forms/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/forms/fields.py b/imagekit/forms/fields.py index 903f6aec..d032ff85 100644 --- a/imagekit/forms/fields.py +++ b/imagekit/forms/fields.py @@ -22,7 +22,7 @@ def __init__(self, processors=None, format=None, options=None, def clean(self, data, initial=None): data = super(ProcessedImageField, self).clean(data, initial) - if data: + if data and data != initial: spec = self.get_spec(source=data) data = generate(spec) From d647678c2e674b4896ee4fe41678a72a82189f80 Mon Sep 17 00:00:00 2001 From: Sean Hayes Date: Wed, 14 Aug 2013 22:07:46 -0400 Subject: [PATCH 326/527] Added global boolean to prevent autodiscover() from being called more than once. --- imagekit/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/imagekit/utils.py b/imagekit/utils.py index 188a1114..13bd843e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -13,6 +13,7 @@ bad_memcached_key_chars = re.compile(ur'[\u0000-\u001f\s]+') +_autodiscovered = False def get_nonabstract_descendants(model): """ Returns all non-abstract descendants of the model. """ @@ -62,11 +63,17 @@ def autodiscover(): Copied from django.contrib.admin """ + global _autodiscovered + + if _autodiscovered: + return from django.conf import settings from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule + _autodiscovered = True + for app in settings.INSTALLED_APPS: mod = import_module(app) # Attempt to import the app's admin module. From c78cbfc089b8e64fd22ea73dbbc61118a953b4dd Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Wed, 14 Aug 2013 22:58:36 -0400 Subject: [PATCH 327/527] Discover image generators during lookup Fixes GH-241 --- imagekit/registry.py | 5 ++++- imagekit/templatetags/imagekit.py | 12 ------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/imagekit/registry.py b/imagekit/registry.py index f1aba898..685b094c 100644 --- a/imagekit/registry.py +++ b/imagekit/registry.py @@ -1,6 +1,6 @@ from .exceptions import AlreadyRegistered, NotRegistered from .signals import content_required, existence_required, source_saved -from .utils import call_strategy_method +from .utils import autodiscover, call_strategy_method class GeneratorRegistry(object): @@ -30,6 +30,8 @@ def unregister(self, id): ' registered' % id) def get(self, id, **kwargs): + autodiscover() + try: generator = self._generators[id] except KeyError: @@ -41,6 +43,7 @@ def get(self, id, **kwargs): return generator def get_ids(self): + autodiscover() return self._generators.keys() def content_required_receiver(self, sender, file, **kwargs): diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index fdf1b148..2df5b4d3 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -43,9 +43,6 @@ def get_variable_name(self, context): return unicode(self._variable_name) def render(self, context): - from ..utils import autodiscover - autodiscover() - variable_name = self.get_variable_name(context) context[variable_name] = get_cachefile(context, self._generator_id, self._generator_kwargs) @@ -60,9 +57,6 @@ def __init__(self, generator_id, generator_kwargs, html_attrs): self._html_attrs = html_attrs def render(self, context): - from ..utils import autodiscover - autodiscover() - file = get_cachefile(context, self._generator_id, self._generator_kwargs) attrs = dict((k, v.resolve(context)) for k, v in @@ -92,9 +86,6 @@ def get_variable_name(self, context): return unicode(self._variable_name) def render(self, context): - from ..utils import autodiscover - autodiscover() - variable_name = self.get_variable_name(context) generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR @@ -119,9 +110,6 @@ def __init__(self, generator_id, dimensions, source, generator_kwargs, html_attr self._html_attrs = html_attrs def render(self, context): - from ..utils import autodiscover - autodiscover() - generator_id = self._generator_id.resolve(context) if self._generator_id else DEFAULT_THUMBNAIL_GENERATOR dimensions = parse_dimensions(self._dimensions.resolve(context)) kwargs = dict((k, v.resolve(context)) for k, v in From 0575011529d26ad092f20b7cac6c9546c4007fdc Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Mon, 19 Aug 2013 21:27:50 +0300 Subject: [PATCH 328/527] Add Python 3 suport and drop support for Python 2.5 --- imagekit/cachefiles/__init__.py | 6 +++++- imagekit/cachefiles/strategies.py | 7 +++++-- imagekit/files.py | 10 +++++++--- imagekit/hashers.py | 16 ++++++++++------ imagekit/lib.py | 23 ++++++++++++++++++++--- imagekit/models/fields/__init__.py | 4 +++- imagekit/templatetags/imagekit.py | 12 ++++++++---- imagekit/utils.py | 5 +++-- setup.py | 8 ++++++-- 9 files changed, 67 insertions(+), 24 deletions(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 2c602ffc..6e2bf19c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -120,7 +120,7 @@ def _generate(self): ) ) - def __nonzero__(self): + def __bool__(self): if not self.name: return False @@ -129,6 +129,10 @@ def __nonzero__(self): existence_required.send(sender=self, file=self) return self.cachefile_backend.exists(self) + def __nonzero__(self): + # Python 2 compatibility + return self.__bool__() + class LazyImageCacheFile(SimpleLazyObject): def __init__(self, generator_id, *args, **kwargs): diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index fba6a0f0..0d11dae8 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -1,4 +1,7 @@ +import six + from django.utils.functional import LazyObject +from ..lib import force_text from ..utils import get_singleton @@ -35,7 +38,7 @@ def __init__(self, callbacks): class StrategyWrapper(LazyObject): def __init__(self, strategy): - if isinstance(strategy, basestring): + if isinstance(strategy, six.string_types): strategy = get_singleton(strategy, 'cache file strategy') elif isinstance(strategy, dict): strategy = DictStrategy(strategy) @@ -50,7 +53,7 @@ def __setstate__(self, state): self._wrapped = state['_wrapped'] def __unicode__(self): - return unicode(self._wrapped) + return force_text(self._wrapped) def __str__(self): return str(self._wrapped) diff --git a/imagekit/files.py b/imagekit/files.py index fb4375c2..e7178880 100644 --- a/imagekit/files.py +++ b/imagekit/files.py @@ -1,6 +1,9 @@ -from django.core.files.base import File, ContentFile -from django.utils.encoding import smart_str, smart_unicode +from __future__ import unicode_literals import os + +from django.core.files.base import File, ContentFile +from django.utils.encoding import smart_str +from .lib import smart_text from .utils import format_to_mimetype, extension_to_mimetype @@ -92,4 +95,5 @@ def __str__(self): return smart_str(self.file.name or '') def __unicode__(self): - return smart_unicode(self.file.name or u'') + # Python 2 + return smart_text(self.file.name or '') diff --git a/imagekit/hashers.py b/imagekit/hashers.py index 4231fa59..12825bda 100644 --- a/imagekit/hashers.py +++ b/imagekit/hashers.py @@ -1,12 +1,16 @@ from copy import copy from hashlib import md5 -from pickle import Pickler, MARK, DICT -from types import DictionaryType +from pickle import MARK, DICT +try: + from pickle import _Pickler +except ImportError: + # Python 2 compatible + from pickle import Pickler as _Pickler from .lib import StringIO -class CanonicalizingPickler(Pickler): - dispatch = copy(Pickler.dispatch) +class CanonicalizingPickler(_Pickler): + dispatch = copy(_Pickler.dispatch) def save_set(self, obj): rv = obj.__reduce_ex__(0) @@ -20,9 +24,9 @@ def save_dict(self, obj): write(MARK + DICT) self.memoize(obj) - self._batch_setitems(sorted(obj.iteritems())) + self._batch_setitems(sorted(obj.items())) - dispatch[DictionaryType] = save_dict + dispatch[dict] = save_dict def pickle(obj): diff --git a/imagekit/lib.py b/imagekit/lib.py index 6da2bfb0..4fe2c05e 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -19,9 +19,12 @@ raise ImportError('ImageKit was unable to import the Python Imaging Library. Please confirm it`s installed and available on your current Python path.') try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO + from io import BytesIO as StringIO +except: + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO try: from logging import NullHandler @@ -31,3 +34,17 @@ class NullHandler(Handler): def emit(self, record): pass + +# Try to import `force_text` available from Django 1.5 +# This function will replace `unicode` used in the code +# If Django version is under 1.5 then use `force_unicde` +# It is used for compatibility between Python 2 and Python 3 +# NOTE: I'm not sure if this is the right place. Maybe this can be in `utils`. +try: + from django.utils.encoding import force_text, smart_text +except ImportError: + # Django < 1.5 + from django.utils.encoding import force_unicode as force_text, smart_unicode as smart_text + +__all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', 'ImageFilter', + 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', 'force_text', 'smart_text'] diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 91c62523..e2ccf26d 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + from django.db import models from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor @@ -13,7 +15,7 @@ def _set_spec_id(self, cls, name): # Generate a spec_id to register the spec with. The default spec id is # ":_" if not spec_id: - spec_id = (u'%s:%s:%s' % (cls._meta.app_label, + spec_id = ('%s:%s:%s' % (cls._meta.app_label, cls._meta.object_name, name)).lower() # Register the spec with the id. This allows specs to be overridden diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 2df5b4d3..25c2cca9 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -1,9 +1,13 @@ +from __future__ import unicode_literals + from django import template from django.utils.html import escape from django.utils.safestring import mark_safe + from .compat import parse_bits from ..cachefiles import ImageCacheFile from ..registry import generator_registry +from ..lib import force_text register = template.Library() @@ -40,7 +44,7 @@ def __init__(self, variable_name, generator_id, generator_kwargs): self._variable_name = variable_name def get_variable_name(self, context): - return unicode(self._variable_name) + return force_text(self._variable_name) def render(self, context): variable_name = self.get_variable_name(context) @@ -70,7 +74,7 @@ def render(self, context): attrs['src'] = file.url attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in attrs.items()) - return mark_safe(u'' % attr_str) + return mark_safe('' % attr_str) class ThumbnailAssignmentNode(template.Node): @@ -83,7 +87,7 @@ def __init__(self, variable_name, generator_id, dimensions, source, generator_kw self._generator_kwargs = generator_kwargs def get_variable_name(self, context): - return unicode(self._variable_name) + return force_text(self._variable_name) def render(self, context): variable_name = self.get_variable_name(context) @@ -131,7 +135,7 @@ def render(self, context): attrs['src'] = file.url attr_str = ' '.join('%s="%s"' % (escape(k), escape(v)) for k, v in attrs.items()) - return mark_safe(u'' % attr_str) + return mark_safe('' % attr_str) def parse_ik_tag_bits(parser, bits): diff --git a/imagekit/utils.py b/imagekit/utils.py index 13bd843e..598be43e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,3 +1,4 @@ +from __future__ import unicode_literals import logging from tempfile import NamedTemporaryFile @@ -11,7 +12,7 @@ from .lib import NullHandler -bad_memcached_key_chars = re.compile(ur'[\u0000-\u001f\s]+') +bad_memcached_key_chars = re.compile(r'[\u0000-\u001f\s]+') _autodiscovered = False @@ -32,7 +33,7 @@ def get_by_qname(path, desc): module, objname = path[:dot], path[dot + 1:] try: mod = import_module(module) - except ImportError, e: + except ImportError as e: raise ImproperlyConfigured('Error importing %s module %s: "%s"' % (desc, module, e)) try: diff --git a/setup.py b/setup.py index da959a01..2f306792 100644 --- a/setup.py +++ b/setup.py @@ -19,10 +19,12 @@ read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read() +def exec_file(filepath, globalz=None, localz=None): + exec(read(filepath), globalz, localz) # Load package meta from the pkgmeta module without loading imagekit. pkgmeta = {} -execfile(os.path.join(os.path.dirname(__file__), +exec_file(os.path.join(os.path.dirname(__file__), 'imagekit', 'pkgmeta.py'), pkgmeta) @@ -51,6 +53,7 @@ install_requires=[ 'django-appconf>=0.5', 'pilkit>=0.2.0', + 'six', ], extras_require={ 'async': ['django-celery>=3.0'], @@ -62,9 +65,10 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', 'Topic :: Utilities' ], ) From 183efabca7573c29908f38de160dd86074a2be2c Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 1 Sep 2013 21:55:37 -0400 Subject: [PATCH 329/527] Delay Django import until needed --- imagekit/importers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/importers.py b/imagekit/importers.py index cddcd838..b2896cf9 100644 --- a/imagekit/importers.py +++ b/imagekit/importers.py @@ -1,4 +1,3 @@ -from django.utils.importlib import import_module import re import sys @@ -22,6 +21,7 @@ def load_module(self, name): if name in sys.modules: return sys.modules[name] + from django.utils.importlib import import_module new_name = self.pattern.sub(r'pilkit.processors\1', name) return import_module(new_name) From 3732b2ee099989ed46e264f031b9b47c414cf6c6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 1 Sep 2013 21:55:58 -0400 Subject: [PATCH 330/527] Insert importer at beginning of list --- imagekit/importers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/importers.py b/imagekit/importers.py index b2896cf9..67d2b513 100644 --- a/imagekit/importers.py +++ b/imagekit/importers.py @@ -26,4 +26,4 @@ def load_module(self, name): return import_module(new_name) -sys.meta_path.append(ProcessorImporter()) +sys.meta_path.insert(0, ProcessorImporter()) From 2e4d435f4f9c7f582ef9db4b00941bec4a87cea6 Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 1 Sep 2013 21:56:28 -0400 Subject: [PATCH 331/527] Test for Python 3 --- setup.py | 6 +++--- tox.ini | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 2f306792..c54c0415 100644 --- a/setup.py +++ b/setup.py @@ -44,9 +44,9 @@ def exec_file(filepath, globalz=None, localz=None): include_package_data=True, tests_require=[ 'beautifulsoup4==4.1.3', - 'nose==1.2.1', - 'nose-progressive==1.3', - 'django-nose==1.1', + 'nose==1.3.0', + 'nose-progressive==1.5', + 'django-nose==1.2', 'Pillow<3.0', ], test_suite='testrunner.run_tests', diff --git a/tox.ini b/tox.ini index 46ca387b..1dc2b41e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,23 @@ [tox] envlist = + py33-django15, + py32-django15, py27-django15, py27-django14, py27-django13, py27-django12, py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test +[testenv:py33-django15] +basepython = python3.3 +deps = + Django>=1.5,<1.6 + +[testenv:py32-django15] +basepython = python3.2 +deps = + Django>=1.5,<1.6 + [testenv:py27-django15] basepython = python2.7 deps = From bf1b45c943715efd8eef2e73ef77d6681da5658f Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Sun, 1 Sep 2013 21:56:42 -0400 Subject: [PATCH 332/527] Add module to sys.modules --- imagekit/importers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imagekit/importers.py b/imagekit/importers.py index 67d2b513..87ba2b69 100644 --- a/imagekit/importers.py +++ b/imagekit/importers.py @@ -23,7 +23,9 @@ def load_module(self, name): from django.utils.importlib import import_module new_name = self.pattern.sub(r'pilkit.processors\1', name) - return import_module(new_name) + mod = import_module(new_name) + sys.modules[name] = mod + return mod sys.meta_path.insert(0, ProcessorImporter()) From 857b1e160e7d9fc5c9e7fd8a9bfb06345d712dcf Mon Sep 17 00:00:00 2001 From: Matthew Tretter Date: Thu, 5 Sep 2013 09:42:09 -0500 Subject: [PATCH 333/527] Update IMAGEKIT_DEFAULT_FILE_STORAGE description --- docs/configuration.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 62161587..33b4f1fb 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -23,7 +23,7 @@ Settings The qualified class name of a Django storage backend to use to save the cached images. If no value is provided for ``IMAGEKIT_DEFAULT_FILE_STORAGE``, - and none is specified by the spec definition, the storage of the source file + and none is specified by the spec definition, `your default file storage`__ will be used. @@ -72,3 +72,6 @@ Settings A function responsible for generating file names for cache files that correspond to image specs. Since you will likely want to base the name of your cache files on the name of the source, this extra setting is provided. + + +__ https://docs.djangoproject.com/en/dev/ref/settings/#default-file-storage From 1c26a2ea5cabc90cc3e4bbc9fa48a9ced4ee7cd6 Mon Sep 17 00:00:00 2001 From: nex2hex Date: Tue, 24 Sep 2013 15:18:59 +0400 Subject: [PATCH 334/527] Add __getstate__ method to ImageCacheFile --- imagekit/cachefiles/__init__.py | 9 +++++++++ tests/test_serialization.py | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 2c602ffc..ec4b356a 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -1,3 +1,4 @@ +from copy import copy from django.conf import settings from django.core.files import File from django.core.files.images import ImageFile @@ -129,6 +130,14 @@ def __nonzero__(self): existence_required.send(sender=self, file=self) return self.cachefile_backend.exists(self) + def __getstate__(self): + state = copy(self.__dict__) + + # file is hidden link to "file" attribute + state.pop('_file', None) + + return state + class LazyImageCacheFile(SimpleLazyObject): def __init__(self, generator_id, *args, **kwargs): diff --git a/tests/test_serialization.py b/tests/test_serialization.py index 85ab1574..9b68af93 100644 --- a/tests/test_serialization.py +++ b/tests/test_serialization.py @@ -4,7 +4,9 @@ """ -from .utils import create_photo, pickleback +from imagekit.cachefiles import ImageCacheFile +from .imagegenerators import TestSpec +from .utils import create_photo, pickleback, get_unique_image_file def test_imagespecfield(): @@ -23,3 +25,13 @@ def test_circular_ref(): instance = create_photo('pickletest3.jpg') instance.thumbnail # Cause thumbnail to be added to instance's __dict__ pickleback(instance) + + +def test_cachefiles(): + spec = TestSpec(source=get_unique_image_file()) + file = ImageCacheFile(spec) + file.url + # remove link to file from spec source generator + # test __getstate__ of ImageCacheFile + file.generator.source = None + pickleback(file) From d6a024ed2d3908d8d5803cc9f2c6947d8e46860d Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Thu, 26 Sep 2013 10:56:22 -0700 Subject: [PATCH 335/527] Bump the version to 3.0.4. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 19516207..c530bc28 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0.3' +__version__ = '3.0.4' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 260c6f5a10beb20265d0a303b43c071b9000de91 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Sun, 27 Oct 2013 13:27:21 +0100 Subject: [PATCH 336/527] Added RQ-based async cache file backend --- imagekit/cachefiles/backends.py | 79 ++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index b1274307..71b5babc 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -17,7 +17,7 @@ def get_default_cachefile_backend(): """ from django.conf import settings return get_singleton(settings.IMAGEKIT_DEFAULT_CACHEFILE_BACKEND, - 'file backend') + 'file backend') class InvalidFileBackendError(ImproperlyConfigured): @@ -116,32 +116,81 @@ def _generate_file(backend, file, force=False): backend.generate_now(file, force=force) +class BaseAsync(Simple): + """ + Base class for cache file backends that generate files asynchronously. + """ + def generate(self, file, force=False): + # Schedule the file for generation, unless we know for sure we don't + # need to. If an already-generated file sneaks through, that's okay; + # ``generate_now`` will catch it. We just want to make sure we don't + # schedule anything we know is unnecessary--but we also don't want to + # force a costly existence check. + state = self.get_state(file, check_if_unknown=False) + if state not in (CacheFileState.GENERATING, CacheFileState.EXISTS): + self.schedule_generation(file, force=force) + + def schedule_generation(self, file, force=False): + # overwrite this to have the file generated in the background, + # e. g. in a worker queue. + raise NotImplementedError + + try: import celery except ImportError: pass -else: - _generate_file = celery.task(ignore_result=True)(_generate_file) -class Async(Simple): +class CeleryAsync(BaseAsync): """ A backend that uses Celery to generate the images. """ - def __init__(self, *args, **kwargs): try: import celery except ImportError: raise ImproperlyConfigured('You must install celery to use' - ' imagekit.cachefiles.backend.Async.') - super(Async, self).__init__(*args, **kwargs) + ' imagekit.cachefiles.backends.CeleryAsync.') + super(CeleryAsync, self).__init__(*args, **kwargs) - def generate(self, file, force=False): - # Schedule the file for generation, unless we know for sure we don't - # need to. If an already-generated file sneaks through, that's okay; - # ``generate_now`` will catch it. We just want to make sure we don't - # schedule anything we know is unnecessary--but we also don't want to - # force a costly existence check. - if self.get_state(file, check_if_unknown=False) not in (CacheFileState.GENERATING, CacheFileState.EXISTS): - _generate_file.delay(self, file, force=force) + def get_task(self): + if not hasattr(self, '_task'): + self._task = celery.task(ignore_result=True)(_generate_file) + return self._task + + def schedule_generation(self, file, force=False): + self.get_task().delay(self, file, force=force) + + +Async = CeleryAsync # backwards compatibility + + +try: + import django_rq +except ImportError: + pass + + +class RQAsync(BaseAsync): + """ + A backend that uses RQ to generate the images. + """ + queue_name = 'default' + + def __init__(self, *args, **kwargs): + try: + import django_rq + except ImportError: + raise ImproperlyConfigured('You must install django_rq to use' + ' imagekit.cachefiles.backends.RQAsync.') + super(RQAsync, self).__init__(*args, **kwargs) + + def get_queue(self): + # not caching property to avoid "can't pickle instancemethod objects", + # see https://github.com/nvie/rq/issues/189 + return django_rq.get_queue(self.queue_name) + + def schedule_generation(self, file, force=False): + self.get_queue().enqueue(_generate_file, args=(self, file), + kwargs=dict(force=force), result_ttl=0) From af3316278d739bbc78c6558bed2d563aba953df5 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Mon, 4 Nov 2013 13:12:02 +0100 Subject: [PATCH 337/527] Cache file backends: dropped the "Async" in class names --- imagekit/cachefiles/backends.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 71b5babc..c7b997ed 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -142,7 +142,7 @@ def schedule_generation(self, file, force=False): pass -class CeleryAsync(BaseAsync): +class Celery(BaseAsync): """ A backend that uses Celery to generate the images. """ @@ -151,8 +151,8 @@ def __init__(self, *args, **kwargs): import celery except ImportError: raise ImproperlyConfigured('You must install celery to use' - ' imagekit.cachefiles.backends.CeleryAsync.') - super(CeleryAsync, self).__init__(*args, **kwargs) + ' imagekit.cachefiles.backends.Celery.') + super(Celery, self).__init__(*args, **kwargs) def get_task(self): if not hasattr(self, '_task'): @@ -163,7 +163,7 @@ def schedule_generation(self, file, force=False): self.get_task().delay(self, file, force=force) -Async = CeleryAsync # backwards compatibility +Async = Celery # backwards compatibility try: @@ -172,7 +172,7 @@ def schedule_generation(self, file, force=False): pass -class RQAsync(BaseAsync): +class RQ(BaseAsync): """ A backend that uses RQ to generate the images. """ @@ -183,8 +183,8 @@ def __init__(self, *args, **kwargs): import django_rq except ImportError: raise ImproperlyConfigured('You must install django_rq to use' - ' imagekit.cachefiles.backends.RQAsync.') - super(RQAsync, self).__init__(*args, **kwargs) + ' imagekit.cachefiles.backends.RQ.') + super(RQ, self).__init__(*args, **kwargs) def get_queue(self): # not caching property to avoid "can't pickle instancemethod objects", From 43afb7c33d85a1369a916d5a6ae243d5562068e4 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Thu, 28 Nov 2013 00:39:57 -0500 Subject: [PATCH 338/527] Fix celery backend --- imagekit/cachefiles/backends.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index c7b997ed..a781dc7f 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -137,9 +137,11 @@ def schedule_generation(self, file, force=False): try: - import celery + from celery import task except ImportError: pass +else: + _celery_task = task(ignore_result=True)(_generate_file) class Celery(BaseAsync): @@ -154,13 +156,8 @@ def __init__(self, *args, **kwargs): ' imagekit.cachefiles.backends.Celery.') super(Celery, self).__init__(*args, **kwargs) - def get_task(self): - if not hasattr(self, '_task'): - self._task = celery.task(ignore_result=True)(_generate_file) - return self._task - def schedule_generation(self, file, force=False): - self.get_task().delay(self, file, force=force) + _celery_task.delay(self, file, force=force) Async = Celery # backwards compatibility From 68cfcce3f1c72033e939a5f305ab6f354cb4060c Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 14 Dec 2013 10:50:58 -0500 Subject: [PATCH 339/527] Correct reference to generateimage tag Closes GH-261 --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index bdfed793..28c42ddb 100644 --- a/README.rst +++ b/README.rst @@ -277,8 +277,8 @@ with the id "imagekit:thumbnail" which, by default, is Second, we're passing two positional arguments (the dimensions and the source image) as opposed to the keyword arguments we used with the generateimage tag. -Like with the generatethumbnail tag, you can also specify additional HTML -attributes for the thumbnail tag, or use it as an assignment tag: +Like with the generateimage tag, you can also specify additional HTML attributes +for the thumbnail tag, or use it as an assignment tag: .. code-block:: html From fb947b19374244bc28dbe09100dfd0e628b16ad4 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sat, 14 Dec 2013 18:56:47 +0200 Subject: [PATCH 340/527] Fix sanitizing cache key under Python 3 --- imagekit/utils.py | 10 +++++++--- tests/test_cachefiles.py | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 598be43e..baaf2343 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -1,14 +1,18 @@ from __future__ import unicode_literals import logging +import re from tempfile import NamedTemporaryFile +from hashlib import md5 from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files import File from django.utils.importlib import import_module -from hashlib import md5 +try: + from django.utils.encoding import force_bytes +except ImportError: + from django.utils.encoding import smart_str as force_bytes from pilkit.utils import * -import re from .lib import NullHandler @@ -148,7 +152,7 @@ def sanitize_cache_key(key): # The also can't be > 250 chars long. Since we don't know what the # user's cache ``KEY_FUNCTION`` setting is like, we'll limit it to 200. if len(new_key) >= 200: - new_key = '%s:%s' % (new_key[:200-33], md5(key).hexdigest()) + new_key = '%s:%s' % (new_key[:200-33], md5(force_bytes(key)).hexdigest()) key = new_key return key diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index 4338a822..ba250fb8 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,4 +1,8 @@ from django.conf import settings +try: + from django.utils.encoding import force_bytes +except ImportError: + from django.utils.encoding import smart_str as force_bytes from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple @@ -73,7 +77,7 @@ def __init__(self, name): eq_(backend.get_key(file), '%s%s:%s' % ( settings.IMAGEKIT_CACHE_PREFIX, '1' * (200 - len(':') - 32 - len(settings.IMAGEKIT_CACHE_PREFIX)), - md5('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename)).hexdigest())) + md5(force_bytes('%s%s-state' % (settings.IMAGEKIT_CACHE_PREFIX, filename))).hexdigest())) def test_lazyfile_stringification(): From c1e16696b14a71049985d6a49a4005a2cd93c593 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 14 Dec 2013 12:54:26 -0500 Subject: [PATCH 341/527] Don't use a raw string with \u escapes Apparently, Python 3.2 doesn't process these in raw strings. See https://mail.python.org/pipermail/python-list/2012-May/624756.html and https://mail.python.org/pipermail/python-dev/2007-May/073042.html --- imagekit/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index baaf2343..c889e288 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -16,7 +16,7 @@ from .lib import NullHandler -bad_memcached_key_chars = re.compile(r'[\u0000-\u001f\s]+') +bad_memcached_key_chars = re.compile('[\u0000-\u001f\\s]+') _autodiscovered = False From 87983c5e6de8030737803791670284ae0bd410ef Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 14 Dec 2013 13:02:21 -0500 Subject: [PATCH 342/527] Move force_bytes into lib module --- imagekit/lib.py | 11 +++++++---- imagekit/utils.py | 6 +----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index 4fe2c05e..12460c9e 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -41,10 +41,13 @@ def emit(self, record): # It is used for compatibility between Python 2 and Python 3 # NOTE: I'm not sure if this is the right place. Maybe this can be in `utils`. try: - from django.utils.encoding import force_text, smart_text + from django.utils.encoding import force_text, force_bytes, smart_text except ImportError: # Django < 1.5 - from django.utils.encoding import force_unicode as force_text, smart_unicode as smart_text + from django.utils.encoding import (force_unicode as force_text, + smart_str as force_bytes, + smart_unicode as smart_text) -__all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', 'ImageFilter', - 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', 'force_text', 'smart_text'] +__all__ = ['Image', 'ImageColor', 'ImageChops', 'ImageEnhance', 'ImageFile', + 'ImageFilter', 'ImageDraw', 'ImageStat', 'StringIO', 'NullHandler', + 'force_text', 'force_bytes', 'smart_text'] diff --git a/imagekit/utils.py b/imagekit/utils.py index c889e288..0973d356 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -8,12 +8,8 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files import File from django.utils.importlib import import_module -try: - from django.utils.encoding import force_bytes -except ImportError: - from django.utils.encoding import smart_str as force_bytes from pilkit.utils import * -from .lib import NullHandler +from .lib import NullHandler, force_bytes bad_memcached_key_chars = re.compile('[\u0000-\u001f\\s]+') From 45f10075b644dc00f3a274223cc1d9aacd1af24b Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 14 Dec 2013 13:03:02 -0500 Subject: [PATCH 343/527] Remove @vstoykov's note. Seems like the right place to me (: --- imagekit/lib.py | 1 - 1 file changed, 1 deletion(-) diff --git a/imagekit/lib.py b/imagekit/lib.py index 12460c9e..5a4240b8 100644 --- a/imagekit/lib.py +++ b/imagekit/lib.py @@ -39,7 +39,6 @@ def emit(self, record): # This function will replace `unicode` used in the code # If Django version is under 1.5 then use `force_unicde` # It is used for compatibility between Python 2 and Python 3 -# NOTE: I'm not sure if this is the right place. Maybe this can be in `utils`. try: from django.utils.encoding import force_text, force_bytes, smart_text except ImportError: From 8a600d30b32aee0dd95ff28c02c6e211e6749160 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 15 Dec 2013 01:58:22 +0200 Subject: [PATCH 344/527] Use force_bytes from imagekit.lib in test_cachefiles --- tests/test_cachefiles.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_cachefiles.py b/tests/test_cachefiles.py index ba250fb8..8a93e716 100644 --- a/tests/test_cachefiles.py +++ b/tests/test_cachefiles.py @@ -1,11 +1,8 @@ from django.conf import settings -try: - from django.utils.encoding import force_bytes -except ImportError: - from django.utils.encoding import smart_str as force_bytes from hashlib import md5 from imagekit.cachefiles import ImageCacheFile, LazyImageCacheFile from imagekit.cachefiles.backends import Simple +from imagekit.lib import force_bytes from nose.tools import raises, eq_ from .imagegenerators import TestSpec from .utils import (assert_file_is_truthy, assert_file_is_falsy, From 26aa19eeef7cbc679f87f7482651386df47d7410 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 15 Dec 2013 02:34:25 +0200 Subject: [PATCH 345/527] Improve logic of contributing ImageSpecFields to Models - If `source` is defined then register source group immediately - If `source` is not defined then create a signal handler and attach it to `class_prepared` signal which will see if there is only one ImageField in the given model. This will fix problems coused in Python 3 about using ImageSpecField without providing a `source`. --- imagekit/models/fields/__init__.py | 53 +++++++++++++++++++----------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index e2ccf26d..61a7dd36 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -1,6 +1,8 @@ from __future__ import unicode_literals from django.db import models +from django.db.models.signals import class_prepared +from django.dispatch import receiver from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor from ...specs import SpecHost @@ -46,27 +48,38 @@ def __init__(self, processors=None, format=None, options=None, def contribute_to_class(self, cls, name): # If the source field name isn't defined, figure it out. - source = self.source - if not source: - image_fields = [f.attname for f in cls._meta.fields if - isinstance(f, models.ImageField)] - if len(image_fields) == 0: - raise Exception( - '%s does not define any ImageFields, so your %s' - ' ImageSpecField has no image to act on.' % - (cls.__name__, name)) - elif len(image_fields) > 1: - raise Exception( - '%s defines multiple ImageFields, but you have not' - ' specified a source for your %s ImageSpecField.' % - (cls.__name__, name)) - source = image_fields[0] - - setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) - self._set_spec_id(cls, name) - # Add the model and field as a source for this spec id - register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) + def register_source_group(source): + setattr(cls, name, ImageSpecFileDescriptor(self, name, source)) + self._set_spec_id(cls, name) + + # Add the model and field as a source for this spec id + register.source_group(self.spec_id, ImageFieldSourceGroup(cls, source)) + + if self.source: + register_source_group(self.source) + else: + # The source argument is not defined + # Then we need to see if there is only one ImageField in that model + # But we need to do that after full model initialization + + @receiver(class_prepared, sender=cls, weak=False) + def handle_model_preparation(sender, **kwargs): + + image_fields = [f.attname for f in cls._meta.fields if + isinstance(f, models.ImageField)] + if len(image_fields) == 0: + raise Exception( + '%s does not define any ImageFields, so your %s' + ' ImageSpecField has no image to act on.' % + (cls.__name__, name)) + elif len(image_fields) > 1: + raise Exception( + '%s defines multiple ImageFields, but you have not' + ' specified a source for your %s ImageSpecField.' % + (cls.__name__, name)) + register_source_group(image_fields[0]) + class ProcessedImageField(models.ImageField, SpecHostField): From 3667c09d8221681d68e9ad93504d3380b61f889b Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Mon, 16 Dec 2013 22:38:05 +0200 Subject: [PATCH 346/527] Add Venelin Stoykov to AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index 255827bf..6f4c2380 100644 --- a/AUTHORS +++ b/AUTHORS @@ -28,6 +28,7 @@ Contributors * `Jannis Leidel`_ * `Sean Bell`_ * `Saul Shanabrook`_ +* `Venelin Stoykov`_ .. _Justin Driscoll: http://github.com/jdriscoll .. _HZDG: http://hzdg.com @@ -49,3 +50,4 @@ Contributors .. _Jannis Leidel: https://github.com/jezdez .. _Sean Bell: https://github.com/seanbell .. _Saul Shanabrook: https://github.com/saulshanabrook +.. _Venelin Stoykov: https://github.com/vstoykov From 452a9c1b3177d6acab61072fd719f7b855d3a879 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Fri, 20 Dec 2013 09:18:57 -0800 Subject: [PATCH 347/527] Tagging 3.1. --- imagekit/pkgmeta.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index c530bc28..caeb043d 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' -__author__ = 'Justin Driscoll, Bryan Veloso, Greg Newman, Chris Drackett, Matthew Tretter, Eric Eldredge' -__version__ = '3.0.4' +__author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' +__version__ = '3.1' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From f113fc7517cf0d0216bc4173e398b56d6fb3e1dc Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Wed, 1 Jan 2014 17:47:36 -0500 Subject: [PATCH 348/527] Use signal.connect for backwards compat The receiver decorator isn't available until Django 1.3. --- imagekit/models/fields/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imagekit/models/fields/__init__.py b/imagekit/models/fields/__init__.py index 61a7dd36..2543f905 100644 --- a/imagekit/models/fields/__init__.py +++ b/imagekit/models/fields/__init__.py @@ -2,7 +2,6 @@ from django.db import models from django.db.models.signals import class_prepared -from django.dispatch import receiver from .files import ProcessedImageFieldFile from .utils import ImageSpecFileDescriptor from ...specs import SpecHost @@ -62,8 +61,6 @@ def register_source_group(source): # The source argument is not defined # Then we need to see if there is only one ImageField in that model # But we need to do that after full model initialization - - @receiver(class_prepared, sender=cls, weak=False) def handle_model_preparation(sender, **kwargs): image_fields = [f.attname for f in cls._meta.fields if @@ -80,6 +77,7 @@ def handle_model_preparation(sender, **kwargs): (cls.__name__, name)) register_source_group(image_fields[0]) + class_prepared.connect(handle_model_preparation, sender=cls, weak=False) class ProcessedImageField(models.ImageField, SpecHostField): From 1ac1a44fc55a7021e5aef358d1af24358dafdb09 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Wed, 1 Jan 2014 15:17:33 -0800 Subject: [PATCH 349/527] Bump the version to 3.2. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index caeb043d..bbb03f38 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.1' +__version__ = '3.2' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From ffd3ba384e4c3eee1355f1eca8cac85ece6f6561 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 21 Jan 2014 10:22:10 -0500 Subject: [PATCH 350/527] Link to Instakit. Related: fish2000/instakit#2 --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index 28c42ddb..a40a8ec7 100644 --- a/README.rst +++ b/README.rst @@ -8,10 +8,15 @@ black-and-white version of a user-uploaded image? ImageKit will make them for you. If you need to programatically generate one image from another, you need ImageKit. +ImageKit comes with a bunch of image processors for common tasks like resizing +and cropping, but you can also create your own. For an idea of what's possible, +check out the `Instakit`__ project. + **For the complete documentation on the latest stable version of ImageKit, see** `ImageKit on RTD`_. .. _`ImageKit on RTD`: http://django-imagekit.readthedocs.org +__ https://github.com/fish2000/instakit Installation From 3799f3c2f47ab0244c3ed4f3996917951c3ab0bd Mon Sep 17 00:00:00 2001 From: Baptiste Mispelon Date: Tue, 21 Jan 2014 17:46:19 +0100 Subject: [PATCH 351/527] Fixed #266 -- Simplified (and renamed) StrategyWrapper. StrategyWrapper was unnecessarily implemented as a LazyObject and it triggered a bug in Django (issue 21840). Changing the lazy object to a function works just as well and bypasses the bug. --- imagekit/cachefiles/strategies.py | 29 ++++++++--------------------- imagekit/specs/__init__.py | 4 ++-- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index 0d11dae8..98f712ed 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -36,24 +36,11 @@ def __init__(self, callbacks): setattr(self, k, v) -class StrategyWrapper(LazyObject): - def __init__(self, strategy): - if isinstance(strategy, six.string_types): - strategy = get_singleton(strategy, 'cache file strategy') - elif isinstance(strategy, dict): - strategy = DictStrategy(strategy) - elif callable(strategy): - strategy = strategy() - self._wrapped = strategy - - def __getstate__(self): - return {'_wrapped': self._wrapped} - - def __setstate__(self, state): - self._wrapped = state['_wrapped'] - - def __unicode__(self): - return force_text(self._wrapped) - - def __str__(self): - return str(self._wrapped) +def load_strategy(strategy): + if isinstance(strategy, six.string_types): + strategy = get_singleton(strategy, 'cache file strategy') + elif isinstance(strategy, dict): + strategy = DictStrategy(strategy) + elif callable(strategy): + strategy = strategy() + return strategy diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index bc331243..054f3fd9 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -2,7 +2,7 @@ from django.conf import settings from django.db.models.fields.files import ImageFieldFile from ..cachefiles.backends import get_default_cachefile_backend -from ..cachefiles.strategies import StrategyWrapper +from ..cachefiles.strategies import load_strategy from .. import hashers from ..exceptions import AlreadyRegistered, MissingSource from ..utils import open_image, get_by_qname, process_image @@ -36,7 +36,7 @@ class BaseImageSpec(object): def __init__(self): self.cachefile_backend = self.cachefile_backend or get_default_cachefile_backend() - self.cachefile_strategy = StrategyWrapper(self.cachefile_strategy) + self.cachefile_strategy = load_strategy(self.cachefile_strategy) def generate(self): raise NotImplementedError From df8d7985510bfac956554e96e35aa520ebb1101d Mon Sep 17 00:00:00 2001 From: Baptiste Mispelon Date: Tue, 21 Jan 2014 17:50:58 +0100 Subject: [PATCH 352/527] Updated tox.ini to test against Django 1.6. --- tox.ini | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tox.ini b/tox.ini index 1dc2b41e..13cb6e4e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,23 +1,38 @@ [tox] envlist = - py33-django15, - py32-django15, - py27-django15, py27-django14, py27-django13, py27-django12, + py33-django16, py33-django15, + py32-django16, py32-django15, + py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test +[testenv:py33-django16] +basepython = python3.3 +deps = + Django>=1.6,<1.7 + [testenv:py33-django15] basepython = python3.3 deps = Django>=1.5,<1.6 +[testenv:py32-django16] +basepython = python3.2 +deps = + Django>=1.6,<1.7 + [testenv:py32-django15] basepython = python3.2 deps = Django>=1.5,<1.6 +[testenv:py27-django16] +basepython = python2.7 +deps = + Django>=1.6,<1.7 + [testenv:py27-django15] basepython = python2.7 deps = From 85d8cb15bb239f717e9f473c95277c143f6fab52 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Tue, 18 Mar 2014 16:37:18 +0100 Subject: [PATCH 353/527] Added a DeprecationWarning if Async cache file backend is used --- imagekit/cachefiles/backends.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index a781dc7f..49bc75c4 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -1,4 +1,5 @@ from ..utils import get_singleton, sanitize_cache_key +import warnings from copy import copy from django.core.cache import get_cache from django.core.exceptions import ImproperlyConfigured @@ -160,7 +161,12 @@ def schedule_generation(self, file, force=False): _celery_task.delay(self, file, force=force) -Async = Celery # backwards compatibility +# Stub class to preserve backwards compatibility and issue a warning +class Async(Celery): + def __init__(self, *args, **kwargs): + message = '{path}.Async is deprecated. Use {path}.Celery instead.' + warnings.warn(message.format(path=__name__), DeprecationWarning) + super(Async, self).__init__(*args, **kwargs) try: From c5a1be3b8e48b3fe3dec9326ff084854b652adc1 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Tue, 18 Mar 2014 17:02:23 +0100 Subject: [PATCH 354/527] Removed unneeded django_rq import --- imagekit/cachefiles/backends.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index a781dc7f..7f121d5f 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -163,12 +163,6 @@ def schedule_generation(self, file, force=False): Async = Celery # backwards compatibility -try: - import django_rq -except ImportError: - pass - - class RQ(BaseAsync): """ A backend that uses RQ to generate the images. From 5b0c789f6bde6252c773eace60afff8ab1d62c52 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Tue, 18 Mar 2014 17:03:16 +0100 Subject: [PATCH 355/527] setup.py: added 'async_rq' extra, django-rq dependency django-rq v0.6.0 is the first version with Python 3 support. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index c54c0415..9a65738c 100644 --- a/setup.py +++ b/setup.py @@ -57,6 +57,7 @@ def exec_file(filepath, globalz=None, localz=None): ], extras_require={ 'async': ['django-celery>=3.0'], + 'async_rq': ['django-rq>=0.6.0'], }, classifiers=[ 'Development Status :: 5 - Production/Stable', From 9be8507ebd128731ee4b71309b4c59493274988a Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Wed, 19 Mar 2014 11:26:10 -0400 Subject: [PATCH 356/527] Always call variable "source_file" This emphasizes that it's a file object and not a PIL image and also connects it to the earlier example which creates that variable. --- README.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index a40a8ec7..de83bf0e 100644 --- a/README.rst +++ b/README.rst @@ -223,7 +223,7 @@ that's what we need to pass to use our thumbnail spec: {% load imagekit %} - {% generateimage 'myapp:thumbnail' source=source_image %} + {% generateimage 'myapp:thumbnail' source=source_file %} This will output the following HTML: @@ -238,7 +238,7 @@ keyword args using two dashes: {% load imagekit %} - {% generateimage 'myapp:thumbnail' source=source_image -- alt="A picture of Me" id="mypicture" %} + {% generateimage 'myapp:thumbnail' source=source_file -- alt="A picture of Me" id="mypicture" %} Not generating HTML image tags? No problem. The tag also functions as an assignment tag, providing access to the underlying file object: @@ -247,7 +247,7 @@ assignment tag, providing access to the underlying file object: {% load imagekit %} - {% generateimage 'myapp:thumbnail' source=source_image as th %} + {% generateimage 'myapp:thumbnail' source=source_file as th %} Click to download a cool {{ th.width }} x {{ th.height }} image! @@ -261,7 +261,7 @@ template tag: {% load imagekit %} - {% thumbnail '100x50' source_image %} + {% thumbnail '100x50' source_file %} Like the generateimage tag, the thumbnail tag outputs an tag: @@ -289,8 +289,8 @@ for the thumbnail tag, or use it as an assignment tag: {% load imagekit %} - {% thumbnail '100x50' source_image -- alt="A picture of Me" id="mypicture" %} - {% thumbnail '100x50' source_image as th %} + {% thumbnail '100x50' source_file -- alt="A picture of Me" id="mypicture" %} + {% thumbnail '100x50' source_file as th %} Using Specs in Forms From 6aa99adf1c5f41af06cfb644b9c85817aa164236 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Wed, 19 Mar 2014 11:27:03 -0400 Subject: [PATCH 357/527] Add note about `open()` Hopefully this prevents people from going through acrobatics to get a File when they've already got one! --- README.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.rst b/README.rst index de83bf0e..e098bae1 100644 --- a/README.rst +++ b/README.rst @@ -147,6 +147,11 @@ on, or what should be done with the result; that's up to you: image_generator = Thumbnail(source=source_file) result = image_generator.generate() +.. note:: + + You don't have to use ``open``! You can use whatever File-like object you + want—including a model's ``ImageField``. + The result of calling ``generate()`` on an image spec is a file-like object containing our resized image, with which you can do whatever you want. For example, if you wanted to save it to disk: From 3056b3efc055fa74e41cbc668c7670efd425d6d0 Mon Sep 17 00:00:00 2001 From: Markus Kaiserswerth Date: Tue, 18 Mar 2014 17:20:24 +0100 Subject: [PATCH 358/527] Simplified RQ cache file backed by using the job decorator --- imagekit/cachefiles/backends.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index e1b744d6..25ce43fa 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -169,25 +169,25 @@ def __init__(self, *args, **kwargs): super(Async, self).__init__(*args, **kwargs) +try: + from django_rq import job +except ImportError: + pass +else: + _rq_job = job('default', result_ttl=0)(_generate_file) + + class RQ(BaseAsync): """ A backend that uses RQ to generate the images. """ - queue_name = 'default' - def __init__(self, *args, **kwargs): try: import django_rq except ImportError: - raise ImproperlyConfigured('You must install django_rq to use' + raise ImproperlyConfigured('You must install django-rq to use' ' imagekit.cachefiles.backends.RQ.') super(RQ, self).__init__(*args, **kwargs) - def get_queue(self): - # not caching property to avoid "can't pickle instancemethod objects", - # see https://github.com/nvie/rq/issues/189 - return django_rq.get_queue(self.queue_name) - def schedule_generation(self, file, force=False): - self.get_queue().enqueue(_generate_file, args=(self, file), - kwargs=dict(force=force), result_ttl=0) + _rq_job.delay(self, file, force=force) From 1d80e83732cb945a0eb9778619ce87e5da15ba57 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Fri, 4 Apr 2014 09:26:54 -0700 Subject: [PATCH 359/527] Bump the version to 3.2.1. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index bbb03f38..b46aebc5 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2' +__version__ = '3.2.1' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 2f7bfe5dc7ebf01310812d8a8638926e12f957d7 Mon Sep 17 00:00:00 2001 From: Colin Wood Date: Fri, 11 Jul 2014 10:07:43 -0400 Subject: [PATCH 360/527] Make sure image files has a name associated. The generate image command will run into issues if the ImageSpecField does not have any image file source associated wit hti. Like a Optional image field. So we can not generate the images for that. So this should check to make sure that it has one. --- imagekit/management/commands/generateimages.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/imagekit/management/commands/generateimages.py b/imagekit/management/commands/generateimages.py index 444440a0..0d9cae5c 100644 --- a/imagekit/management/commands/generateimages.py +++ b/imagekit/management/commands/generateimages.py @@ -1,6 +1,7 @@ from django.core.management.base import BaseCommand import re from ...registry import generator_registry, cachefile_registry +from ...exceptions import MissingSource class Command(BaseCommand): @@ -22,14 +23,15 @@ def handle(self, *args, **options): for generator_id in generators: self.stdout.write('Validating generator: %s\n' % generator_id) - for file in cachefile_registry.get(generator_id): - self.stdout.write(' %s\n' % file) - try: - # TODO: Allow other validation actions through command option - file.generate() - except Exception as err: - # TODO: How should we handle failures? Don't want to error, but should call it out more than this. - self.stdout.write(' FAILED: %s\n' % err) + for image_file in cachefile_registry.get(generator_id): + if image_file.name: + self.stdout.write(' %s\n' % image_file.name) + try: + image_file.generate() + except MissingSource as err: + self.stdout.write('\t No source associated with\n') + except Exception as err: + self.stdout.write('\tFailed %s\n' % (err)) def compile_patterns(self, generator_ids): return [self.compile_pattern(id) for id in generator_ids] From d013b82c7f3a03ea15f101ab48e9a911be26d34c Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Mon, 14 Jul 2014 12:24:05 -0700 Subject: [PATCH 361/527] Bump version to 3.2.2. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index b46aebc5..81478c31 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.1' +__version__ = '3.2.2' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 491bc244a49451bb31196c973654ecf159b59464 Mon Sep 17 00:00:00 2001 From: Paul Garner Date: Wed, 23 Jul 2014 19:20:58 +0100 Subject: [PATCH 362/527] allow Django template to supress missing src errors --- imagekit/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/exceptions.py b/imagekit/exceptions.py index 9aba0181..be790443 100644 --- a/imagekit/exceptions.py +++ b/imagekit/exceptions.py @@ -14,7 +14,7 @@ class MissingGeneratorId(Exception): class MissingSource(ValueError): - pass + silent_variable_failure = True # Aliases for backwards compatibility From 06b06dbcedd0689f19e4b38c235bc1e520e8fea7 Mon Sep 17 00:00:00 2001 From: danxshap Date: Mon, 8 Sep 2014 18:28:49 -0400 Subject: [PATCH 363/527] Catch autodiscover module import error --- imagekit/utils.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 0973d356..31db1e86 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -76,16 +76,21 @@ def autodiscover(): _autodiscovered = True for app in settings.INSTALLED_APPS: - mod = import_module(app) - # Attempt to import the app's admin module. + # As of Django 1.7, settings.INSTALLED_APPS may contain classes instead of modules, hence the try/except + # See here: https://docs.djangoproject.com/en/dev/releases/1.7/#introspecting-applications try: - import_module('%s.imagegenerators' % app) - except: - # Decide whether to bubble up this error. If the app just - # doesn't have an imagegenerators module, we can ignore the error - # attempting to import it, otherwise we want it to bubble up. - if module_has_submodule(mod, 'imagegenerators'): - raise + mod = import_module(app) + # Attempt to import the app's admin module. + try: + import_module('%s.imagegenerators' % app) + except: + # Decide whether to bubble up this error. If the app just + # doesn't have an imagegenerators module, we can ignore the error + # attempting to import it, otherwise we want it to bubble up. + if module_has_submodule(mod, 'imagegenerators'): + raise + except ImportError: + pass def get_logger(logger_name='imagekit', add_null_handler=True): From 945a5623efa64e470294577a352c996ed11fcd62 Mon Sep 17 00:00:00 2001 From: Nabil Date: Sun, 21 Sep 2014 18:50:44 -0400 Subject: [PATCH 364/527] Fixed minor spelling error in README.rst --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index e098bae1..80e0e758 100644 --- a/README.rst +++ b/README.rst @@ -136,7 +136,7 @@ particularly when the processing being done depends on user input. format = 'JPEG' options = {'quality': 60} -It's probaby not surprising that this class is capable of processing an image +It's probably not surprising that this class is capable of processing an image in the exact same way as our ImageSpecField above. However, unlike with the image spec model field, this class doesn't define what source the spec is acting on, or what should be done with the result; that's up to you: From f5b23a67bd4ab60203343741c923b0920a753fe0 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 23 Sep 2014 14:59:20 -0400 Subject: [PATCH 365/527] Remove test dir __init__.py Related: matthewwithanm/pilkit#14 --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 From 9f4192a7c6f8e185b9cc4e04941ef570d66ec335 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 23 Sep 2014 18:29:52 -0400 Subject: [PATCH 366/527] Ignore my Python3 virtualenv --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 40b09c6a..575a8003 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ dist /tests/media/* !/tests/media/lenna.png /venv +/venv3 /.env From c92f53c1b09f5e7dc01790d7a5f611a1bd2f0856 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 23 Sep 2014 18:32:00 -0400 Subject: [PATCH 367/527] Test that Optimistic strategy doesn't cause reads Using the Optimistic strategy should prevent IO ops when you cast the file as a boolean. --- setup.py | 1 + tests/test_optimistic_strategy.py | 37 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/test_optimistic_strategy.py diff --git a/setup.py b/setup.py index 9a65738c..8f60701f 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ def exec_file(filepath, globalz=None, localz=None): 'nose-progressive==1.5', 'django-nose==1.2', 'Pillow<3.0', + 'mock==1.0.1', ], test_suite='testrunner.run_tests', install_requires=[ diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py new file mode 100644 index 00000000..d3ce9598 --- /dev/null +++ b/tests/test_optimistic_strategy.py @@ -0,0 +1,37 @@ +from nose.tools import assert_true, assert_false +from imagekit.cachefiles import ImageCacheFile +from mock import Mock +from .utils import create_image +from django.core.files.storage import FileSystemStorage +from imagekit.cachefiles.backends import Simple as SimpleCFBackend +from imagekit.cachefiles.strategies import Optimistic as OptimisticStrategy + + +class ImageGenerator(object): + def generate(self): + return create_image() + + def get_hash(self): + return 'abc123' + + +def get_image_cache_file(): + storage = Mock(FileSystemStorage) + backend = SimpleCFBackend() + strategy = OptimisticStrategy() + generator = ImageGenerator() + return ImageCacheFile(generator, storage=storage, + cachefile_backend=backend, + cachefile_strategy=strategy) + + +def test_no_io_on_bool(): + """ + When checking the truthiness of an ImageCacheFile, the storage shouldn't + peform IO operations. + + """ + file = get_image_cache_file() + bool(file) + assert_false(file.storage.exists.called) + assert_false(file.storage.open.called) From 00b4388245f7777276af351e3afd68af2417c426 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 23 Sep 2014 18:35:38 -0400 Subject: [PATCH 368/527] Support should_verify_existence on strategies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents extra IO. Different defaults are used for async backends since we can’t assume that `existence_required` resulted in existence synchronously. --- imagekit/cachefiles/__init__.py | 9 ++++++++- imagekit/cachefiles/backends.py | 2 ++ imagekit/cachefiles/strategies.py | 3 +++ tests/utils.py | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/imagekit/cachefiles/__init__.py b/imagekit/cachefiles/__init__.py index 34892ec1..2ba5cb8c 100644 --- a/imagekit/cachefiles/__init__.py +++ b/imagekit/cachefiles/__init__.py @@ -128,7 +128,14 @@ def __bool__(self): # Dispatch the existence_required signal before checking to see if the # file exists. This gives the strategy a chance to create the file. existence_required.send(sender=self, file=self) - return self.cachefile_backend.exists(self) + + try: + check = self.cachefile_strategy.should_verify_existence(self) + except AttributeError: + # All synchronous backends should have created the file as part of + # `existence_required` if they wanted to. + check = getattr(self.cachefile_backend, 'is_async', False) + return self.cachefile_backend.exists(self) if check else True def __getstate__(self): state = copy(self.__dict__) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 25ce43fa..1512f518 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -121,6 +121,8 @@ class BaseAsync(Simple): """ Base class for cache file backends that generate files asynchronously. """ + is_async = True + def generate(self, file, force=False): # Schedule the file for generation, unless we know for sure we don't # need to. If an already-generated file sneaks through, that's okay; diff --git a/imagekit/cachefiles/strategies.py b/imagekit/cachefiles/strategies.py index 98f712ed..bcd8211e 100644 --- a/imagekit/cachefiles/strategies.py +++ b/imagekit/cachefiles/strategies.py @@ -29,6 +29,9 @@ class Optimistic(object): def on_source_saved(self, file): file.generate() + def should_verify_existence(self, file): + return False + class DictStrategy(object): def __init__(self, callbacks): diff --git a/tests/utils.py b/tests/utils.py index 5a9f1c5c..b6c49520 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -77,5 +77,7 @@ class DummyAsyncCacheFileBackend(Simple): A cache file backend meant to simulate async generation. """ + is_async = True + def generate(self, file, force=False): pass From bbf48a79539493fcade9b5cdb4b1c637b64961ee Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Tue, 23 Sep 2014 18:39:33 -0400 Subject: [PATCH 369/527] Test that there isn't IO done when you get a URL --- tests/test_optimistic_strategy.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_optimistic_strategy.py b/tests/test_optimistic_strategy.py index d3ce9598..18b8f3fd 100644 --- a/tests/test_optimistic_strategy.py +++ b/tests/test_optimistic_strategy.py @@ -35,3 +35,15 @@ def test_no_io_on_bool(): bool(file) assert_false(file.storage.exists.called) assert_false(file.storage.open.called) + + +def test_no_io_on_url(): + """ + When getting the URL of an ImageCacheFile, the storage shouldn't be + checked. + + """ + file = get_image_cache_file() + file.url + assert_false(file.storage.exists.called) + assert_false(file.storage.open.called) From 8d35dad5fc63de919936d0407d105c36c87a1b14 Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Fri, 26 Sep 2014 20:42:53 -0400 Subject: [PATCH 370/527] Add test to illustrate GH-295 --- tests/test_no_extra_queries.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/test_no_extra_queries.py diff --git a/tests/test_no_extra_queries.py b/tests/test_no_extra_queries.py new file mode 100644 index 00000000..89c68cb4 --- /dev/null +++ b/tests/test_no_extra_queries.py @@ -0,0 +1,16 @@ +from nose.tools import assert_false +from mock import Mock, PropertyMock, patch +from .models import Photo + + +def test_dont_access_source(): + """ + Touching the source may trigger an unneeded query. + See + + """ + pmock = PropertyMock() + pmock.__get__ = Mock() + with patch.object(Photo, 'original_image', pmock): + photo = Photo() # noqa + assert_false(pmock.__get__.called) From 78a1ccaf2fc6bc04bffa8edb8523307387b6f81e Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Fri, 26 Sep 2014 22:21:24 -0400 Subject: [PATCH 371/527] Only include fetched fields in initial hash of sources Should avoid unnecessary queries, as detailed in GH-295. --- imagekit/specs/sourcegroups.py | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/imagekit/specs/sourcegroups.py b/imagekit/specs/sourcegroups.py index 2008f593..d8ea3a7f 100644 --- a/imagekit/specs/sourcegroups.py +++ b/imagekit/specs/sourcegroups.py @@ -72,18 +72,19 @@ def update_source_hashes(self, instance): """ self.init_instance(instance) - instance._ik['source_hashes'] = dict((attname, hash(file_field)) - for attname, file_field in self.get_field_dict(instance).items()) + instance._ik['source_hashes'] = dict( + (attname, hash(getattr(instance, attname))) + for attname in self.get_source_fields(instance)) return instance._ik['source_hashes'] - def get_field_dict(self, instance): + def get_source_fields(self, instance): """ - Returns the source fields for the given instance, in a dictionary whose - keys are the field names and values are the fields themselves. + Returns a list of the source fields for the given instance. """ - return dict((src.image_field, getattr(instance, src.image_field)) for - src in self._source_groups if isinstance(instance, src.model_class)) + return set(src.image_field + for src in self._source_groups + if isinstance(instance, src.model_class)) @ik_model_receiver def post_save_receiver(self, sender, instance=None, created=False, raw=False, **kwargs): @@ -91,14 +92,22 @@ def post_save_receiver(self, sender, instance=None, created=False, raw=False, ** self.init_instance(instance) old_hashes = instance._ik.get('source_hashes', {}).copy() new_hashes = self.update_source_hashes(instance) - for attname, file in self.get_field_dict(instance).items(): - if file and old_hashes[attname] != new_hashes[attname]: + for attname in self.get_source_fields(instance): + file = getattr(instance, attname) + if file and old_hashes.get(attname) != new_hashes[attname]: self.dispatch_signal(source_saved, file, sender, instance, attname) @ik_model_receiver def post_init_receiver(self, sender, instance=None, **kwargs): - self.update_source_hashes(instance) + self.init_instance(instance) + source_fields = self.get_source_fields(instance) + local_fields = dict((field.name, field) + for field in instance._meta.local_fields + if field.name in source_fields) + instance._ik['source_hashes'] = dict( + (attname, hash(file_field)) + for attname, file_field in local_fields.items()) def dispatch_signal(self, signal, file, model_class, instance, attname): """ From e2ae8508661f9e66b3d47106049a2df968d2e93f Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 27 Sep 2014 17:52:21 -0400 Subject: [PATCH 372/527] Revert "Remove test dir __init__.py" This reverts commit f5b23a67bd4ab60203343741c923b0920a753fe0. I forgot we were using 'tests.settings' as a settings module path. --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b From 3a2150e51587152623093dea176caa061c4c09ec Mon Sep 17 00:00:00 2001 From: Matthew Dapena-Tretter Date: Sat, 27 Sep 2014 18:03:07 -0400 Subject: [PATCH 373/527] Exclude tests from dist Related: matthewwithanm/pilkit#14 --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 0adbc507..94be0c57 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,3 +3,4 @@ include LICENSE include README.rst recursive-include docs * recursive-include imagekit/templates * +prune tests From 5f4f7070f4db89b8210d0da87ae78819a551e601 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sat, 27 Sep 2014 22:20:40 -0700 Subject: [PATCH 374/527] Bump the version to 3.2.3. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 81478c31..b7d0e816 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.2' +__version__ = '3.2.3' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 1ac3399737dde40bee15a5a75c46d4ebdbc22bf8 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Sun, 28 Sep 2014 18:31:33 +0300 Subject: [PATCH 375/527] Deprecate `imagekit.processors` submodules - `base`, `crop`, `resize`, and `utils` are now placed in `pilkit` app - remove magic compatibility between `imagekit.processors` and `pilkit.procesors` --- imagekit/__init__.py | 1 - imagekit/importers.py | 31 ------------------------------- imagekit/processors.py | 5 ----- imagekit/processors/__init__.py | 12 ++++++++++++ imagekit/processors/base.py | 7 +++++++ imagekit/processors/crop.py | 7 +++++++ imagekit/processors/resize.py | 7 +++++++ imagekit/processors/utils.py | 5 +++++ 8 files changed, 38 insertions(+), 37 deletions(-) delete mode 100644 imagekit/importers.py delete mode 100644 imagekit/processors.py create mode 100644 imagekit/processors/__init__.py create mode 100644 imagekit/processors/base.py create mode 100644 imagekit/processors/crop.py create mode 100644 imagekit/processors/resize.py create mode 100644 imagekit/processors/utils.py diff --git a/imagekit/__init__.py b/imagekit/__init__.py index d78a1300..6e92fb34 100644 --- a/imagekit/__init__.py +++ b/imagekit/__init__.py @@ -1,5 +1,4 @@ # flake8: noqa -from . import importers from . import conf from . import generatorlibrary from .specs import ImageSpec diff --git a/imagekit/importers.py b/imagekit/importers.py deleted file mode 100644 index 87ba2b69..00000000 --- a/imagekit/importers.py +++ /dev/null @@ -1,31 +0,0 @@ -import re -import sys - - -class ProcessorImporter(object): - """ - The processors were moved to the PILKit project so they could be used - separtely from ImageKit (which has a bunch of Django dependencies). However, - there's no real need to expose this fact (and we want to maintain backwards - compatibility), so we proxy all "imagekit.processors" imports to - "pilkit.processors" using this object. - - """ - pattern = re.compile(r'^imagekit\.processors((\..*)?)$') - - def find_module(self, name, path=None): - if self.pattern.match(name): - return self - - def load_module(self, name): - if name in sys.modules: - return sys.modules[name] - - from django.utils.importlib import import_module - new_name = self.pattern.sub(r'pilkit.processors\1', name) - mod = import_module(new_name) - sys.modules[name] = mod - return mod - - -sys.meta_path.insert(0, ProcessorImporter()) diff --git a/imagekit/processors.py b/imagekit/processors.py deleted file mode 100644 index dbf0b030..00000000 --- a/imagekit/processors.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Looking for processors? They have moved to PILKit. See imagekit.importers for -details. - -""" diff --git a/imagekit/processors/__init__.py b/imagekit/processors/__init__.py new file mode 100644 index 00000000..7c3532f0 --- /dev/null +++ b/imagekit/processors/__init__.py @@ -0,0 +1,12 @@ +from pilkit.processors import * + +__all__ = [ + # Base + 'ProcessorPipeline', 'Adjust', 'Reflection', 'Transpose', + 'Anchor', 'MakeOpaque', + # Crop + 'TrimBorderColor', 'Crop', 'SmartCrop', + # Resize + 'Resize', 'ResizeToCover', 'ResizeToFill', 'SmartResize', + 'ResizeCanvas', 'AddBorder', 'ResizeToFit', 'Thumbnail' +] diff --git a/imagekit/processors/base.py b/imagekit/processors/base.py new file mode 100644 index 00000000..c94a966b --- /dev/null +++ b/imagekit/processors/base.py @@ -0,0 +1,7 @@ +import warnings + +from pilkit.processors.base import * + +warnings.warn('imagekit.processors.base is deprecated use imagekit.processors instead', DeprecationWarning) + +__all__ = ['ProcessorPipeline', 'Adjust', 'Reflection', 'Transpose', 'Anchor', 'MakeOpaque'] diff --git a/imagekit/processors/crop.py b/imagekit/processors/crop.py new file mode 100644 index 00000000..b519d1a4 --- /dev/null +++ b/imagekit/processors/crop.py @@ -0,0 +1,7 @@ +import warnings + +from pilkit.processors.crop import * + +warnings.warn('imagekit.processors.crop is deprecated use imagekit.processors instead', DeprecationWarning) + +__all__ = ['TrimBorderColor', 'Crop', 'SmartCrop'] diff --git a/imagekit/processors/resize.py b/imagekit/processors/resize.py new file mode 100644 index 00000000..9c1cb30d --- /dev/null +++ b/imagekit/processors/resize.py @@ -0,0 +1,7 @@ +import warnings + +from pilkit.processors.resize import * + +warnings.warn('imagekit.processors.resize is deprecated use imagekit.processors instead', DeprecationWarning) + +__all__ = ['Resize', 'ResizeToCover', 'ResizeToFill', 'SmartResize', 'ResizeCanvas', 'AddBorder', 'ResizeToFit', 'Thumbnail'] diff --git a/imagekit/processors/utils.py b/imagekit/processors/utils.py new file mode 100644 index 00000000..4b829cd1 --- /dev/null +++ b/imagekit/processors/utils.py @@ -0,0 +1,5 @@ +import warnings + +from pilkit.processors.utils import * + +warnings.warn('imagekit.processors.utils is deprecated use pilkit.processors.utils instead', DeprecationWarning) From 1d5606b3d74f702c20f806c9e7e1aef8e08380bd Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sun, 28 Sep 2014 13:23:32 -0700 Subject: [PATCH 376/527] Bump the version to 3.2.4. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index b7d0e816..c9608e57 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.3' +__version__ = '3.2.4' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From d9fe8d24b2cc91cb2780fafc557706304256307a Mon Sep 17 00:00:00 2001 From: Niklas A Emanuelsson Date: Fri, 2 Jan 2015 15:40:40 +0100 Subject: [PATCH 377/527] Explicitly setting serializer for celery task --- imagekit/cachefiles/backends.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 1512f518..89498564 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -144,7 +144,7 @@ def schedule_generation(self, file, force=False): except ImportError: pass else: - _celery_task = task(ignore_result=True)(_generate_file) + _celery_task = task(ignore_result=True, serializer='pickle')(_generate_file) class Celery(BaseAsync): @@ -153,7 +153,7 @@ class Celery(BaseAsync): """ def __init__(self, *args, **kwargs): try: - import celery + import celery # noqa except ImportError: raise ImproperlyConfigured('You must install celery to use' ' imagekit.cachefiles.backends.Celery.') @@ -185,7 +185,7 @@ class RQ(BaseAsync): """ def __init__(self, *args, **kwargs): try: - import django_rq + import django_rq # noqa except ImportError: raise ImproperlyConfigured('You must install django-rq to use' ' imagekit.cachefiles.backends.RQ.') From a159e7c75bdff8ec6fe9d78094d1ce66ed88f470 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Mon, 5 Jan 2015 15:58:38 -0800 Subject: [PATCH 378/527] Bump the version to 3.2.5. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index c9608e57..8f7aa941 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.4' +__version__ = '3.2.5' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 207849e48e2ec37027f2b32ad2875a69aa0644b1 Mon Sep 17 00:00:00 2001 From: David Ray Date: Tue, 27 Jan 2015 07:57:48 -0500 Subject: [PATCH 379/527] Fix typo --- docs/caching.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/caching.rst b/docs/caching.rst index b482f1f0..dfb2dd35 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -71,7 +71,7 @@ The default works like this: * If not, caches that information for 5 seconds * If it does, caches that information in the ``IMAGEKIT_CACHE_BACKEND`` -If file doesn't exsit, generates it immediately and synchronously +If file doesn't exist, generates it immediately and synchronously That pretty much covers the architecture of the caching layer, and its default From f6e0033aaeac6a68db81f4dafa623af7a79b59c7 Mon Sep 17 00:00:00 2001 From: Tino de Bruijn Date: Fri, 20 Feb 2015 17:58:53 +0100 Subject: [PATCH 380/527] Add note about usage of optimistic strategy with async backend --- docs/caching.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/caching.rst b/docs/caching.rst index dfb2dd35..6aa7a1e1 100644 --- a/docs/caching.rst +++ b/docs/caching.rst @@ -132,7 +132,7 @@ As mentioned above, image generation is normally done synchronously. through the default cache file backend. However, you can also take advantage of deferred generation. In order to do this, you'll need to do two things: -1) install `django-celery`__ +1) install `celery`__ (or `django-celery`__ if you are bound to Celery<3.1) 2) tell ImageKit to use the async cachefile backend. To do this for all specs, set the ``IMAGEKIT_DEFAULT_CACHEFILE_BACKEND`` in your settings @@ -164,8 +164,23 @@ Or, in Python: else: url = '/path/to/placeholder.jpg' +.. note:: + + If you are using an "async" backend in combination with the "optimistic" + cache file strategy (see `Removing Safeguards`_ below), checking for + thruthiness as described above will not work. The "optimistic" backend is + very optimistic so to say, and removes the check. Create and use the + following strategy to a) have images only created on save, and b) retain + the ability to check whether the images have already been created:: + + class ImagekitOnSaveStrategy(object): + def on_source_saved(self, file): + file.generate() + + __ https://pypi.python.org/pypi/django-celery +__ http://www.celeryproject.org Removing Safeguards From 41f45a4fe79afb2d19f82ed4297ddb54c4f31698 Mon Sep 17 00:00:00 2001 From: ILYA Date: Wed, 25 Feb 2015 19:51:28 +0300 Subject: [PATCH 381/527] Updated importlib import to fix DeprecationWarning (for django 1.8) --- imagekit/utils.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/imagekit/utils.py b/imagekit/utils.py index 31db1e86..20ecda6e 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -7,7 +7,10 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files import File -from django.utils.importlib import import_module +try: + from importlib import import_module +except ImportError: + from django.utils.importlib import import_module from pilkit.utils import * from .lib import NullHandler, force_bytes @@ -70,7 +73,10 @@ def autodiscover(): return from django.conf import settings - from django.utils.importlib import import_module + try: + from importlib import import_module + except ImportError: + from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule _autodiscovered = True From d6bbff47f0efff77221f9bad1094aa9ec474aac9 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Thu, 26 Feb 2015 10:28:38 -0800 Subject: [PATCH 382/527] Bump the version to 3.2.6. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index 8f7aa941..a702f9ce 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.5' +__version__ = '3.2.6' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 561b5d7ab7e341d16396546499e956d8528def5a Mon Sep 17 00:00:00 2001 From: Cesar de la Vega Date: Sun, 10 May 2015 23:59:26 +0100 Subject: [PATCH 383/527] Fixes imports in README example for ProcessedImageField --- README.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/README.rst b/README.rst index 80e0e758..bb3bb002 100644 --- a/README.rst +++ b/README.rst @@ -88,6 +88,7 @@ class: from django.db import models from imagekit.models import ProcessedImageField + from imagekit.processors import ResizeToFill class Profile(models.Model): avatar_thumbnail = ProcessedImageField(upload_to='avatars', From e455768352bca8de64c2857d8bae1239946f750e Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 13 May 2015 01:13:37 +0300 Subject: [PATCH 384/527] Add test environments for Python3.4 and Django1.7 and Django1.8 --- setup.py | 9 ++++--- tests/test_fields.py | 1 + tox.ini | 64 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 8f60701f..4406e491 100644 --- a/setup.py +++ b/setup.py @@ -44,9 +44,9 @@ def exec_file(filepath, globalz=None, localz=None): include_package_data=True, tests_require=[ 'beautifulsoup4==4.1.3', - 'nose==1.3.0', - 'nose-progressive==1.5', - 'django-nose==1.2', + 'nose>=1.3.6,<1.4', + 'nose-progressive==1.5.1', + 'django-nose>=1.2,<=1.4', 'Pillow<3.0', 'mock==1.0.1', ], @@ -67,10 +67,13 @@ def exec_file(filepath, globalz=None, localz=None): 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', 'Topic :: Utilities' ], ) diff --git a/tests/test_fields.py b/tests/test_fields.py index df513ee4..6afb6cf7 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -26,6 +26,7 @@ class TestForm(forms.ModelForm): class Meta: model = ImageModel + fields = 'image', upload_file = get_image_file() file_dict = {'image': SimpleUploadedFile('abc.jpg', upload_file.read())} diff --git a/tox.ini b/tox.ini index 13cb6e4e..1c60ca2b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,43 @@ [tox] envlist = - py33-django16, py33-django15, - py32-django16, py32-django15, - py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, + py34-django18, py34-django17, py34-django16, + py33-django18, py33-django17, py33-django16, py33-django15, + py32-django18, py32-django17, py32-django16, py32-django15, + py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test +[testenv:py34-django18] +basepython = python3.4 +deps = + Django>=1.8,<1.9 + django-nose==1.4 + +[testenv:py34-django17] +basepython = python3.4 +deps = + Django>=1.7,<1.8 + django-nose==1.4 + +[testenv:py34-django16] +basepython = python3.4 +deps = + Django>=1.6,<1.7 + +[testenv:py33-django18] +basepython = python3.3 +deps = + Django>=1.8,<1.9 + django-nose==1.4 + +[testenv:py33-django17] +basepython = python3.3 +deps = + Django>=1.7,<1.8 + django-nose==1.4 + [testenv:py33-django16] basepython = python3.3 deps = @@ -18,6 +48,18 @@ basepython = python3.3 deps = Django>=1.5,<1.6 +[testenv:py32-django18] +basepython = python3.4 +deps = + Django>=1.8,<1.9 + django-nose==1.4 + +[testenv:py32-django17] +basepython = python3.4 +deps = + Django>=1.7,<1.8 + django-nose==1.4 + [testenv:py32-django16] basepython = python3.2 deps = @@ -28,6 +70,18 @@ basepython = python3.2 deps = Django>=1.5,<1.6 +[testenv:py27-django18] +basepython = python2.7 +deps = + Django>=1.8,<1.9 + django-nose==1.4 + +[testenv:py27-django17] +basepython = python2.7 +deps = + Django>=1.7,<1.8 + django-nose==1.4 + [testenv:py27-django16] basepython = python2.7 deps = @@ -47,11 +101,13 @@ deps = basepython = python2.7 deps = Django>=1.3,<1.4 + django-nose==1.2 [testenv:py27-django12] basepython = python2.7 deps = Django>=1.2,<1.3 + django-nose==1.2 [testenv:py26-django15] basepython = python2.6 @@ -67,8 +123,10 @@ deps = basepython = python2.6 deps = Django>=1.3,<1.4 + django-nose==1.2 [testenv:py26-django12] basepython = python2.6 deps = Django>=1.2,<1.3 + django-nose==1.2 From 458f80050c715103b78f3535f34a76bb44954c97 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Fri, 5 Jun 2015 03:01:07 +0300 Subject: [PATCH 385/527] Do not use progressive when we are not running in terminal --- tests/settings.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/settings.py b/tests/settings.py index 01b93a23..0c519896 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -34,7 +34,6 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' NOSE_ARGS = [ '-s', - '--with-progressive', # When the tests are run --with-coverage, these args configure coverage # reporting (requires coverage to be installed). @@ -45,6 +44,9 @@ '--cover-html-dir=%s' % os.path.join(BASE_PATH, 'cover') ] +if os.getenv('TERM'): + NOSE_ARGS.append('--with-progressive') + DEBUG = True TEMPLATE_DEBUG = DEBUG CACHE_BACKEND = 'locmem://' From eb81b9c88c0c44593fbc6322c13daaa00be3c2af Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 2 Aug 2015 00:01:30 -0700 Subject: [PATCH 386/527] Fixes open source file never getting closed In a processes that generates many images, you could run into a cituation with too man files being open. This results in: IOError: [Errno 24] Too many open files --- imagekit/specs/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/imagekit/specs/__init__.py b/imagekit/specs/__init__.py index 054f3fd9..829dce1f 100644 --- a/imagekit/specs/__init__.py +++ b/imagekit/specs/__init__.py @@ -153,9 +153,11 @@ def generate(self): self.source.open() img = open_image(self.source) - return process_image(img, processors=self.processors, - format=self.format, autoconvert=self.autoconvert, - options=self.options) + new_image = process_image(img, processors=self.processors, + format=self.format, autoconvert=self.autoconvert, + options=self.options) + self.source.close() + return new_image def create_spec_class(class_attrs): From 7cdda460708ad520d2a6565b6d8fd5afe46a87d0 Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 2 Aug 2015 00:05:43 -0700 Subject: [PATCH 387/527] Fixes open cache file never getting closed In a processes that generates many images, you could run into a cituation with too man files being open. This results in: IOError: [Errno 24] Too many open files --- imagekit/cachefiles/backends.py | 1 + 1 file changed, 1 insertion(+) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 89498564..5e7025a8 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -96,6 +96,7 @@ def generate_now(self, file, force=False): self.set_state(file, CacheFileState.GENERATING) file._generate() self.set_state(file, CacheFileState.EXISTS) + file.close() class Simple(CachedFileBackend): From 75763b80f80af284d536bb5c8d820203f45931cc Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Sun, 23 Aug 2015 17:58:46 -0700 Subject: [PATCH 388/527] Bump the version to 3.2.7. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index a702f9ce..a7e84c80 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.6' +__version__ = '3.2.7' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 0a0708d2d6e34db6abbc5f204ab4c81d9be252a8 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Thu, 29 Oct 2015 23:03:48 +0100 Subject: [PATCH 389/527] Use a compat method to wrap the new way of retrieving the cache engine --- imagekit/cachefiles/backends.py | 3 +-- imagekit/utils.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/imagekit/cachefiles/backends.py b/imagekit/cachefiles/backends.py index 5e7025a8..e615f2ea 100644 --- a/imagekit/cachefiles/backends.py +++ b/imagekit/cachefiles/backends.py @@ -1,7 +1,6 @@ -from ..utils import get_singleton, sanitize_cache_key +from ..utils import get_singleton, get_cache, sanitize_cache_key import warnings from copy import copy -from django.core.cache import get_cache from django.core.exceptions import ImproperlyConfigured diff --git a/imagekit/utils.py b/imagekit/utils.py index 20ecda6e..d768f570 100644 --- a/imagekit/utils.py +++ b/imagekit/utils.py @@ -151,6 +151,16 @@ def call_strategy_method(file, method_name): fn(file) +def get_cache(backend, **kwargs): + try: + from django.core.cache import caches + except ImportError: + from django.core.cache import get_cache + return get_cache(backend, **kwargs) + + return caches[backend] + + def sanitize_cache_key(key): if settings.IMAGEKIT_USE_MEMCACHED_SAFE_CACHE_KEY: # Memcached keys can't contain whitespace or control characters. From fbf15befb86da577c0bfa3c1794b01947f117208 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Thu, 29 Oct 2015 23:27:02 +0100 Subject: [PATCH 390/527] Do not take a decision on which cache to use in DEBUG mode maybe the developer wants to test his cache configuration locally, or maybe he has to test different types of caches, we just don't know --- imagekit/conf.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 2900da1f..4485eb13 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -17,25 +17,16 @@ class ImageKitConf(AppConf): def configure_cache_backend(self, value): if value is None: - try: - from django.core.cache.backends.dummy import DummyCache - except ImportError: - dummy_cache = 'dummy://' - else: - dummy_cache = 'django.core.cache.backends.dummy.DummyCache' - # DEFAULT_CACHE_ALIAS doesn't exist in Django<=1.2 try: from django.core.cache import DEFAULT_CACHE_ALIAS as default_cache_alias except ImportError: default_cache_alias = 'default' - if settings.DEBUG: - value = dummy_cache - elif default_cache_alias in getattr(settings, 'CACHES', {}): + if default_cache_alias in getattr(settings, 'CACHES', {}): value = default_cache_alias else: - value = getattr(settings, 'CACHE_BACKEND', None) or dummy_cache + raise ValueError("The default cache alias '%s' is not available in CACHES" % value) return value From e155b632cdfc434e9b42f48ce4a15fe1f2623352 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Fri, 30 Oct 2015 00:24:50 +0100 Subject: [PATCH 391/527] Handle cases where DEFAULT_CACHE_ALIAS is None in old Django versions --- imagekit/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 4485eb13..6bd39d1b 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -19,7 +19,8 @@ def configure_cache_backend(self, value): if value is None: # DEFAULT_CACHE_ALIAS doesn't exist in Django<=1.2 try: - from django.core.cache import DEFAULT_CACHE_ALIAS as default_cache_alias + from django.core.cache import DEFAULT_CACHE_ALIAS + default_cache_alias = DEFAULT_CACHE_ALIAS or 'default' except ImportError: default_cache_alias = 'default' From 5855e97997c8c54913f15f1102cb298f084b5522 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Fri, 30 Oct 2015 16:23:28 +0100 Subject: [PATCH 392/527] Cleaner implementation thanks to @vstoykov explanation --- imagekit/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 6bd39d1b..4485eb13 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -19,8 +19,7 @@ def configure_cache_backend(self, value): if value is None: # DEFAULT_CACHE_ALIAS doesn't exist in Django<=1.2 try: - from django.core.cache import DEFAULT_CACHE_ALIAS - default_cache_alias = DEFAULT_CACHE_ALIAS or 'default' + from django.core.cache import DEFAULT_CACHE_ALIAS as default_cache_alias except ImportError: default_cache_alias = 'default' From 7f36f897f8a934900b505c454c887428a6b2feb8 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 00:22:55 +0100 Subject: [PATCH 393/527] Update the doc to reflect the new `IMAGEKIT_CACHE_BACKEND` behavior --- docs/configuration.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 33b4f1fb..f65ed526 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -44,11 +44,15 @@ Settings .. attribute:: IMAGEKIT_CACHE_BACKEND - :default: If ``DEBUG`` is ``True``, ``'django.core.cache.backends.dummy.DummyCache'``. - Otherwise, ``'default'``. + :default: ``'default'`` - The Django cache backend to be used to store information like the state of - cached images (i.e. validated or not). + The Django cache backend alias to retrieve the shared cache instance defined + in your settings, as described in the `Django cache section`_. + + The cache is then used to store information like the state of cached + images (i.e. validated or not). + +.. _`Django cache section`: https://docs.djangoproject.com/en/1.8/topics/cache/#accessing-the-cache .. attribute:: IMAGEKIT_CACHE_PREFIX From c858936e0c4f06dc5ce136b1bef9a192b3d12a16 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:36:01 +0100 Subject: [PATCH 394/527] Add tox env for django 1.9 supported python versions can be found at https://docs.djangoproject.com/en/1.9/releases/1.9/ --- tox.ini | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 1c60ca2b..7d0642db 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,27 @@ [tox] envlist = - py34-django18, py34-django17, py34-django16, + py35-django19, + py34-django19, py34-django18, py34-django17, py34-django16, py33-django18, py33-django17, py33-django16, py33-django15, py32-django18, py32-django17, py32-django16, py32-django15, - py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, + py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test +[testenv:py35-django19] +basepython = python3.5 +deps = + git+https://github.com/django/django.git@stable/1.9.x#egg=Django + django-nose==1.4 + +[testenv:py34-django19] +basepython = python3.4 +deps = + git+https://github.com/django/django.git@stable/1.9.x#egg=Django + django-nose==1.4 + [testenv:py34-django18] basepython = python3.4 deps = @@ -70,6 +83,12 @@ basepython = python3.2 deps = Django>=1.5,<1.6 +[testenv:py27-django19] +basepython = python2.7 +deps = + git+https://github.com/django/django.git@stable/1.9.x#egg=Django + django-nose==1.4 + [testenv:py27-django18] basepython = python2.7 deps = From ecf5e892e24930d4b5c9c219800ccc462b519f12 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:37:44 +0100 Subject: [PATCH 395/527] Use the env conf for travis to split the test builds --- .travis.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.travis.yml b/.travis.yml index 80c5fd19..2625e69a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,35 @@ language: python python: - 2.7 + +env: + - TOX_ENV=py26-django12 + - TOX_ENV=py26-django13 + - TOX_ENV=py26-django14 + - TOX_ENV=py26-django15 + - TOX_ENV=py26-django16 + - TOX_ENV=py27-django12 + - TOX_ENV=py27-django13 + - TOX_ENV=py27-django14 + - TOX_ENV=py27-django15 + - TOX_ENV=py27-django16 + - TOX_ENV=py27-django17 + - TOX_ENV=py27-django18 + - TOX_ENV=py27-django19 + - TOX_ENV=py32-django15 + - TOX_ENV=py32-django16 + - TOX_ENV=py32-django17 + - TOX_ENV=py32-django18 + - TOX_ENV=py33-django15 + - TOX_ENV=py33-django16 + - TOX_ENV=py33-django17 + - TOX_ENV=py33-django18 + - TOX_ENV=py34-django16 + - TOX_ENV=py34-django17 + - TOX_ENV=py34-django18 + - TOX_ENV=py34-django19 + - TOX_ENV=py35-django19 + install: pip install tox --use-mirrors script: tox notifications: From c89a63edbee94ec778039f205a9f69c9c57a3ffd Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:38:40 +0100 Subject: [PATCH 396/527] Allow travis to fail for the python3.5 interpreter not yet available --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2625e69a..4e24a1d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,11 @@ env: - TOX_ENV=py34-django19 - TOX_ENV=py35-django19 +matrix: + # Python 3.5 not yet available on travis, watch this to see when it is. + allow_failures: + - env: TOX_ENV=py35-django19 + install: pip install tox --use-mirrors script: tox notifications: From 820d2f00ebf2be52966baff9813f85ec2f231ad4 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:39:06 +0100 Subject: [PATCH 397/527] Allow the test to fail fast --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4e24a1d6..2f1da0be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ env: matrix: # Python 3.5 not yet available on travis, watch this to see when it is. + fast_finish: true allow_failures: - env: TOX_ENV=py35-django19 From b475de7b4815a0ea407c5d0e5621f711f0fd58c2 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:39:46 +0100 Subject: [PATCH 398/527] Enable the new travis architecture for speed and reliability --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2f1da0be..c4f39020 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: python -python: - - 2.7 +python: "2.7" +sudo: false env: - TOX_ENV=py26-django12 From 6fabad9749e07175620901ccf129ea3d931e497f Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 11:43:17 +0100 Subject: [PATCH 399/527] Tells tox to only run the designated env --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4f39020..563884a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,11 @@ matrix: allow_failures: - env: TOX_ENV=py35-django19 -install: pip install tox --use-mirrors -script: tox +install: + - pip install tox --use-mirrors + +script: + - tox -e $TOX_ENV + notifications: irc: "irc.freenode.org#imagekit" From 97dc4b6cb2e65f958a387f86e1a3c946f430c390 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 18:51:07 +0100 Subject: [PATCH 400/527] Work a compatibility implementation for Django 1.2 --- imagekit/conf.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/imagekit/conf.py b/imagekit/conf.py index 4485eb13..84dffb6b 100644 --- a/imagekit/conf.py +++ b/imagekit/conf.py @@ -23,10 +23,21 @@ def configure_cache_backend(self, value): except ImportError: default_cache_alias = 'default' - if default_cache_alias in getattr(settings, 'CACHES', {}): + caches = getattr(settings, 'CACHES', None) + if caches is None: + # Support Django<=1.2 there is no default `CACHES` setting + try: + from django.core.cache.backends.dummy import DummyCache + except ImportError: + dummy_cache = 'dummy://' + else: + dummy_cache = 'django.core.cache.backends.dummy.DummyCache' + return dummy_cache + + if default_cache_alias in caches: value = default_cache_alias else: - raise ValueError("The default cache alias '%s' is not available in CACHES" % value) + raise ValueError("The default cache alias '%s' is not available in CACHES" % default_cache_alias) return value From e79d2ba60ebe8c5ab711894ec519ca1f27af9944 Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 19:02:02 +0100 Subject: [PATCH 401/527] Add a missing env to the tox matrix --- tox.ini | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 7d0642db..744d2340 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ envlist = py33-django18, py33-django17, py33-django16, py33-django15, py32-django18, py32-django17, py32-django16, py32-django15, py27-django19, py27-django18, py27-django17, py27-django16, py27-django15, py27-django14, py27-django13, py27-django12, - py26-django15, py26-django14, py26-django13, py26-django12 + py26-django16, py26-django15, py26-django14, py26-django13, py26-django12 [testenv] commands = python setup.py test @@ -128,6 +128,11 @@ deps = Django>=1.2,<1.3 django-nose==1.2 +[testenv:py26-django16] +basepython = python2.6 +deps = + Django>=1.6,<1.7 + [testenv:py26-django15] basepython = python2.6 deps = From cec8cd7780334167b80bdadc3984722c967740fc Mon Sep 17 00:00:00 2001 From: Pierre Dulac Date: Sat, 31 Oct 2015 19:12:35 +0100 Subject: [PATCH 402/527] Update django-nose version to work with Django 1.9 --- setup.py | 2 +- tox.ini | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 4406e491..f26c81ab 100644 --- a/setup.py +++ b/setup.py @@ -46,7 +46,7 @@ def exec_file(filepath, globalz=None, localz=None): 'beautifulsoup4==4.1.3', 'nose>=1.3.6,<1.4', 'nose-progressive==1.5.1', - 'django-nose>=1.2,<=1.4', + 'django-nose>=1.2,<1.5', 'Pillow<3.0', 'mock==1.0.1', ], diff --git a/tox.ini b/tox.ini index 744d2340..2bc14a5e 100644 --- a/tox.ini +++ b/tox.ini @@ -14,13 +14,13 @@ commands = python setup.py test basepython = python3.5 deps = git+https://github.com/django/django.git@stable/1.9.x#egg=Django - django-nose==1.4 + django-nose==1.4.2 [testenv:py34-django19] basepython = python3.4 deps = git+https://github.com/django/django.git@stable/1.9.x#egg=Django - django-nose==1.4 + django-nose==1.4.2 [testenv:py34-django18] basepython = python3.4 @@ -87,7 +87,7 @@ deps = basepython = python2.7 deps = git+https://github.com/django/django.git@stable/1.9.x#egg=Django - django-nose==1.4 + git+https://github.com/django-nose/django-nose@master#egg=django-nose [testenv:py27-django18] basepython = python2.7 From 53fb3a872202ae3128fee16f9a1c585ca76736a2 Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Tue, 8 Dec 2015 11:38:39 -0800 Subject: [PATCH 403/527] Bump version number. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index a7e84c80..e9fe7e06 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' __author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' -__version__ = '3.2.7' +__version__ = '3.3' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From 7903efd9b7c2a484b3ee128b2f04ba3b33c02caf Mon Sep 17 00:00:00 2001 From: Bryan Veloso Date: Tue, 8 Dec 2015 11:39:03 -0800 Subject: [PATCH 404/527] Add @vstoykov to the author list. --- imagekit/pkgmeta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imagekit/pkgmeta.py b/imagekit/pkgmeta.py index e9fe7e06..5872ac01 100644 --- a/imagekit/pkgmeta.py +++ b/imagekit/pkgmeta.py @@ -1,5 +1,5 @@ __title__ = 'django-imagekit' -__author__ = 'Matthew Tretter, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' +__author__ = 'Matthew Tretter, Venelin Stoykov, Eric Eldredge, Bryan Veloso, Greg Newman, Chris Drackett, Justin Driscoll' __version__ = '3.3' __license__ = 'BSD' __all__ = ['__title__', '__author__', '__version__', '__license__'] From d280ad8989fd8a4f4bac4d8d498acc906f46ac47 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Thu, 24 Dec 2015 23:37:53 +0200 Subject: [PATCH 405/527] Fix test requirements for django 1.9 and Python3.5 --- setup.py | 4 ++-- tox.ini | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index f26c81ab..618225a1 100644 --- a/setup.py +++ b/setup.py @@ -43,8 +43,8 @@ def exec_file(filepath, globalz=None, localz=None): zip_safe=False, include_package_data=True, tests_require=[ - 'beautifulsoup4==4.1.3', - 'nose>=1.3.6,<1.4', + 'beautifulsoup4==4.4.0', + 'nose>=1.3.6,<1.5', 'nose-progressive==1.5.1', 'django-nose>=1.2,<1.5', 'Pillow<3.0', diff --git a/tox.ini b/tox.ini index 2bc14a5e..e73b8cd6 100644 --- a/tox.ini +++ b/tox.ini @@ -13,20 +13,20 @@ commands = python setup.py test [testenv:py35-django19] basepython = python3.5 deps = - git+https://github.com/django/django.git@stable/1.9.x#egg=Django + Django>=1.9,<1.10 django-nose==1.4.2 [testenv:py34-django19] basepython = python3.4 deps = - git+https://github.com/django/django.git@stable/1.9.x#egg=Django + Django>=1.9,<1.10 django-nose==1.4.2 [testenv:py34-django18] basepython = python3.4 deps = Django>=1.8,<1.9 - django-nose==1.4 + django-nose==1.4.2 [testenv:py34-django17] basepython = python3.4 @@ -43,7 +43,7 @@ deps = basepython = python3.3 deps = Django>=1.8,<1.9 - django-nose==1.4 + django-nose==1.4.2 [testenv:py33-django17] basepython = python3.3 @@ -65,7 +65,7 @@ deps = basepython = python3.4 deps = Django>=1.8,<1.9 - django-nose==1.4 + django-nose==1.4.2 [testenv:py32-django17] basepython = python3.4 @@ -86,14 +86,14 @@ deps = [testenv:py27-django19] basepython = python2.7 deps = - git+https://github.com/django/django.git@stable/1.9.x#egg=Django - git+https://github.com/django-nose/django-nose@master#egg=django-nose + Django>=1.9,<1.10 + django-nose==1.4.2 [testenv:py27-django18] basepython = python2.7 deps = Django>=1.8,<1.9 - django-nose==1.4 + django-nose==1.4.2 [testenv:py27-django17] basepython = python2.7 From 340e26cd670bd09767f71bea3724c53ae050be10 Mon Sep 17 00:00:00 2001 From: Venelin Stoykov Date: Wed, 23 Dec 2015 21:54:33 +0200 Subject: [PATCH 406/527] Move compat module outside of templatetags package --- imagekit/{templatetags => }/compat.py | 0 imagekit/templatetags/imagekit.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename imagekit/{templatetags => }/compat.py (100%) diff --git a/imagekit/templatetags/compat.py b/imagekit/compat.py similarity index 100% rename from imagekit/templatetags/compat.py rename to imagekit/compat.py diff --git a/imagekit/templatetags/imagekit.py b/imagekit/templatetags/imagekit.py index 25c2cca9..5a69c915 100644 --- a/imagekit/templatetags/imagekit.py +++ b/imagekit/templatetags/imagekit.py @@ -4,7 +4,7 @@ from django.utils.html import escape from django.utils.safestring import mark_safe -from .compat import parse_bits +from ..compat import parse_bits from ..cachefiles import ImageCacheFile from ..registry import generator_registry from ..lib import force_text From 4e370fdc5912eb1b2e83f886d43e59c8d07b555d Mon Sep 17 00:00:00 2001 From: Michael Fladischer Date: Tue, 9 Feb 2016 11:43:05 +0100 Subject: [PATCH 407/527] Replace Lenna image in tests with a truly free alternative. The Lenna image used in image processing tests is considered problematic due to its unclear copyright status. Right now it is considered to be "overlooked" by the copyright holder Playboy. A suitable replacement image is already provided in the libav sources which is licensed under the Expat (MIT) license and thus truly free. This replaces the Lenna image with the one from the libav project. --- .gitignore | 2 +- tests/assets/Lenna.png | Bin 473831 -> 0 bytes tests/assets/lenna-800x600-white-border.jpg | Bin 202370 -> 0 bytes tests/assets/lenna-800x600.jpg | Bin 211057 -> 0 bytes tests/media/lenna.png | Bin 473831 -> 0 bytes tests/media/reference.png | Bin 0 -> 119422 bytes tests/utils.py | 5 +++-- 7 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 tests/assets/Lenna.png delete mode 100644 tests/assets/lenna-800x600-white-border.jpg delete mode 100644 tests/assets/lenna-800x600.jpg delete mode 100644 tests/media/lenna.png create mode 100644 tests/media/reference.png diff --git a/.gitignore b/.gitignore index 575a8003..c571f485 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ MANIFEST build dist /tests/media/* -!/tests/media/lenna.png +!/tests/media/reference.png /venv /venv3 /.env diff --git a/tests/assets/Lenna.png b/tests/assets/Lenna.png deleted file mode 100644 index 59ef68aabd033341028ccd2b1f6c5871c02b9d7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 473831 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 z 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