From 2ab956aa33a32740a4543d7abad00bd2cbe3b64c Mon Sep 17 00:00:00 2001 From: maru21 Date: Mon, 8 Dec 2025 21:31:05 +0100 Subject: [PATCH] Upload files to "/" --- compile.sh | 4 + kindleConnect.sh | 4 + lodepng.c | 7231 ++++++++++++++++++++++++++++++++++++++++++++++ lodepng.h | 2173 ++++++++++++++ penpad | Bin 0 -> 643984 bytes 5 files changed, 9412 insertions(+) create mode 100644 compile.sh create mode 100644 kindleConnect.sh create mode 100644 lodepng.c create mode 100644 lodepng.h create mode 100644 penpad diff --git a/compile.sh b/compile.sh new file mode 100644 index 0000000..23329e2 --- /dev/null +++ b/compile.sh @@ -0,0 +1,4 @@ +clear +rm -i penpad +arm-linux-gnueabihf-gcc -O2 -static -o penpad penpad_fb2.c lodepng.c +file penpad diff --git a/kindleConnect.sh b/kindleConnect.sh new file mode 100644 index 0000000..218b218 --- /dev/null +++ b/kindleConnect.sh @@ -0,0 +1,4 @@ +DEV="enxee4900000000" + +sudo ip addr add 192.168.15.201/24 dev $DEV +sudo ip link set $DEV up diff --git a/lodepng.c b/lodepng.c new file mode 100644 index 0000000..b91d677 --- /dev/null +++ b/lodepng.c @@ -0,0 +1,7231 @@ +/* +LodePNG version 20250506 + +Copyright (c) 2005-2025 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +The manual and changelog are in the header file "lodepng.h" +Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. +*/ + +#include "lodepng.h" + +#ifdef LODEPNG_COMPILE_DISK +#include /* LONG_MAX */ +#include /* file handling */ +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ALLOCATORS +#include /* allocations */ +#endif /* LODEPNG_COMPILE_ALLOCATORS */ + +#if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ +#pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ +#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ +#endif /*_MSC_VER */ + +const char* LODEPNG_VERSION_STRING = "20250506"; + +/* +This source file is divided into the following large parts. The code sections +with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. +-Tools for C and common code for PNG and Zlib +-C Code for Zlib (huffman, deflate, ...) +-C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) +-The C++ wrapper around all of the above +*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // Tools for C, and common code for PNG and Zlib. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*The malloc, realloc and free functions defined here with "lodepng_" in front +of the name, so that you can easily change them to others related to your +platform if needed. Everything else in the code calls these. Pass +-DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out +#define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and +define them in your own project's source files without needing to change +lodepng source code. Don't forget to remove "static" if you copypaste them +from here.*/ + +#ifdef LODEPNG_COMPILE_ALLOCATORS +static void* lodepng_malloc(size_t size) { +#ifdef LODEPNG_MAX_ALLOC + if(size > LODEPNG_MAX_ALLOC) return 0; +#endif + return malloc(size); +} + +/* NOTE: when realloc returns NULL, it leaves the original memory untouched */ +static void* lodepng_realloc(void* ptr, size_t new_size) { +#ifdef LODEPNG_MAX_ALLOC + if(new_size > LODEPNG_MAX_ALLOC) return 0; +#endif + return realloc(ptr, new_size); +} + +static void lodepng_free(void* ptr) { + free(ptr); +} +#else /*LODEPNG_COMPILE_ALLOCATORS*/ +/* TODO: support giving additional void* payload to the custom allocators */ +void* lodepng_malloc(size_t size); +void* lodepng_realloc(void* ptr, size_t new_size); +void lodepng_free(void* ptr); +#endif /*LODEPNG_COMPILE_ALLOCATORS*/ + +/* convince the compiler to inline a function, for use when this measurably improves performance */ +/* inline is not available in C90, but use it when supported by the compiler */ +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(__cplusplus) && (__cplusplus >= 199711L)) +#define LODEPNG_INLINE inline +#else +#define LODEPNG_INLINE /* not available */ +#endif + +/* restrict is not available in C90, but use it when supported by the compiler */ +#if (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) ||\ + (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ + (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus)) +#define LODEPNG_RESTRICT __restrict +#else +#define LODEPNG_RESTRICT /* not available */ +#endif + +/* Replacements for C library functions such as memcpy and strlen, to support platforms +where a full C library is not available. The compiler can recognize them and compile +to something as fast. */ + +static void lodepng_memcpy(void* LODEPNG_RESTRICT dst, + const void* LODEPNG_RESTRICT src, size_t size) { + size_t i; + for(i = 0; i < size; i++) ((char*)dst)[i] = ((const char*)src)[i]; +} + +static void lodepng_memset(void* LODEPNG_RESTRICT dst, + int value, size_t num) { + size_t i; + for(i = 0; i < num; i++) ((char*)dst)[i] = (char)value; +} + +/* does not check memory out of bounds, do not use on untrusted data */ +static size_t lodepng_strlen(const char* a) { + const char* orig = a; + /* avoid warning about unused function in case of disabled COMPILE... macros */ + (void)(&lodepng_strlen); + while(*a) a++; + return (size_t)(a - orig); +} + +#define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER) +/* Safely check if adding two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_addofl(size_t a, size_t b, size_t* result) { + *result = a + b; /* Unsigned addition is well defined and safe in C90 */ + return *result < a; +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)*/ + +#ifdef LODEPNG_COMPILE_DECODER +/* Safely check if multiplying two integers will overflow (no undefined +behavior, compiler removing the code, etc...) and output result. */ +static int lodepng_mulofl(size_t a, size_t b, size_t* result) { + *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */ + return (a != 0 && *result / a != b); +} + +#ifdef LODEPNG_COMPILE_ZLIB +/* Safely check if a + b > c, even if overflow could happen. */ +static int lodepng_gtofl(size_t a, size_t b, size_t c) { + size_t d; + if(lodepng_addofl(a, b, &d)) return 1; + return d > c; +} +#endif /*LODEPNG_COMPILE_ZLIB*/ +#endif /*LODEPNG_COMPILE_DECODER*/ + + +/* +Often in case of an error a value is assigned to a variable and then it breaks +out of a loop (to go to the cleanup phase of a function). This macro does that. +It makes the error handling code shorter and more readable. + +Example: if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83); +*/ +#define CERROR_BREAK(errorvar, code){\ + errorvar = code;\ + break;\ +} + +/*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ +#define ERROR_BREAK(code) CERROR_BREAK(error, code) + +/*Set error var to the error code, and return it.*/ +#define CERROR_RETURN_ERROR(errorvar, code){\ + errorvar = code;\ + return code;\ +} + +/*Try the code, if it returns error, also return the error.*/ +#define CERROR_TRY_RETURN(call){\ + unsigned error = call;\ + if(error) return error;\ +} + +/*Set error var to the error code, and return from the void function.*/ +#define CERROR_RETURN(errorvar, code){\ + errorvar = code;\ + return;\ +} + +/* +About uivector, ucvector and string: +-All of them wrap dynamic arrays or text strings in a similar way. +-LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. +-The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. +-They're not used in the interface, only internally in this file as static functions. +-As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. +*/ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_ENCODER +/*dynamic vector of unsigned ints*/ +typedef struct uivector { + unsigned* data; + size_t size; /*size in number of unsigned longs*/ + size_t allocsize; /*allocated size in bytes*/ +} uivector; + +static void uivector_cleanup(void* p) { + ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; + lodepng_free(((uivector*)p)->data); + ((uivector*)p)->data = NULL; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_resize(uivector* p, size_t size) { + size_t allocsize = size * sizeof(unsigned); + if(allocsize > p->allocsize) { + size_t newsize = allocsize + (p->allocsize >> 1u); + void* data = lodepng_realloc(p->data, newsize); + if(data) { + p->allocsize = newsize; + p->data = (unsigned*)data; + } + else return 0; /*error: not enough memory*/ + } + p->size = size; + return 1; /*success*/ +} + +static void uivector_init(uivector* p) { + p->data = NULL; + p->size = p->allocsize = 0; +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned uivector_push_back(uivector* p, unsigned c) { + if(!uivector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* /////////////////////////////////////////////////////////////////////////// */ + +/*dynamic vector of unsigned chars*/ +typedef struct ucvector { + unsigned char* data; + size_t size; /*used size*/ + size_t allocsize; /*allocated size*/ +} ucvector; + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_reserve(ucvector* p, size_t size) { + if(size > p->allocsize) { + size_t newsize = size + (p->allocsize >> 1u); + void* data = lodepng_realloc(p->data, newsize); + if(data) { + p->allocsize = newsize; + p->data = (unsigned char*)data; + } + else return 0; /*error: not enough memory*/ + } + return 1; /*success*/ +} + +/*returns 1 if success, 0 if failure ==> nothing done*/ +static unsigned ucvector_resize(ucvector* p, size_t size) { + p->size = size; + return ucvector_reserve(p, size); +} + +static ucvector ucvector_init(unsigned char* buffer, size_t size) { + ucvector v; + v.data = buffer; + v.allocsize = v.size = size; + return v; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +/*free string pointer and set it to NULL*/ +static void string_cleanup(char** out) { + lodepng_free(*out); + *out = NULL; +} + +/*also appends null termination character*/ +static char* alloc_string_sized(const char* in, size_t insize) { + char* out = (char*)lodepng_malloc(insize + 1); + if(out) { + lodepng_memcpy(out, in, insize); + out[insize] = 0; + } + return out; +} + +/* dynamically allocates a new string with a copy of the null terminated input text */ +static char* alloc_string(const char* in) { + return alloc_string_sized(in, lodepng_strlen(in)); +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG) +static unsigned lodepng_read32bitInt(const unsigned char* buffer) { + return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) | + ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]); +} +#endif /*defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)*/ + +#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) +/*buffer must have at least 4 allocated bytes available*/ +static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { + buffer[0] = (unsigned char)((value >> 24) & 0xff); + buffer[1] = (unsigned char)((value >> 16) & 0xff); + buffer[2] = (unsigned char)((value >> 8) & 0xff); + buffer[3] = (unsigned char)((value ) & 0xff); +} +#endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / File IO / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DISK + +/* returns negative value on error. This should be pure C compatible, so no fstat. */ +static long lodepng_filesize(FILE* file) { + long size; + if(fseek(file, 0, SEEK_END) != 0) return -1; + size = ftell(file); + /* It may give LONG_MAX as directory size, this is invalid for us. */ + if(size == LONG_MAX) return -1; + if(fseek(file, 0, SEEK_SET) != 0) return -1; + return size; +} + +/* Allocates the output buffer to the file size and reads the file into it. Returns error code.*/ +static unsigned lodepng_load_file_(unsigned char** out, size_t* outsize, FILE* file) { + long size = lodepng_filesize(file); + if(size < 0) return 78; + *outsize = (size_t)size; + *out = (unsigned char*)lodepng_malloc((size_t)size); + if(!(*out) && size > 0) return 83; /*the above malloc failed*/ + if(fread(*out, 1, *outsize, file) != *outsize) return 78; + return 0; /*ok*/ +} + +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { + unsigned error; + FILE* file = fopen(filename, "rb"); + if(!file) return 78; + error = lodepng_load_file_(out, outsize, file); + fclose(file); + return error; +} + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { + FILE* file = fopen(filename, "wb" ); + if(!file) return 79; + fwrite(buffer, 1, buffersize, file); + fclose(file); + return 0; +} + +#endif /*LODEPNG_COMPILE_DISK*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of common code and tools. Begin of Zlib related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_ENCODER + +typedef struct { + ucvector* data; + unsigned char bp; /*ok to overflow, indicates bit pos inside byte*/ +} LodePNGBitWriter; + +static void LodePNGBitWriter_init(LodePNGBitWriter* writer, ucvector* data) { + writer->data = data; + writer->bp = 0; +} + +/*TODO: this ignores potential out of memory errors*/ +#define WRITEBIT(writer, bit){\ + /* append new byte */\ + if(((writer->bp) & 7u) == 0) {\ + if(!ucvector_resize(writer->data, writer->data->size + 1)) return;\ + writer->data->data[writer->data->size - 1] = 0;\ + }\ + (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\ + ++writer->bp;\ +} + +/* LSB of value is written first, and LSB of bytes is used first */ +static void writeBits(LodePNGBitWriter* writer, unsigned value, size_t nbits) { + if(nbits == 1) { /* compiler should statically compile this case if nbits == 1 */ + WRITEBIT(writer, value); + } else { + /* TODO: increase output size only once here rather than in each WRITEBIT */ + size_t i; + for(i = 0; i != nbits; ++i) { + WRITEBIT(writer, (unsigned char)((value >> i) & 1)); + } + } +} + +/* This one is to use for adding huffman symbol, the value bits are written MSB first */ +static void writeBitsReversed(LodePNGBitWriter* writer, unsigned value, size_t nbits) { + size_t i; + for(i = 0; i != nbits; ++i) { + /* TODO: increase output size only once here rather than in each WRITEBIT */ + WRITEBIT(writer, (unsigned char)((value >> (nbits - 1u - i)) & 1u)); + } +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +typedef struct { + const unsigned char* data; + size_t size; /*size of data in bytes*/ + size_t bitsize; /*size of data in bits, end of valid bp values, should be 8*size*/ + size_t bp; + unsigned buffer; /*buffer for reading bits. NOTE: 'unsigned' must support at least 32 bits*/ +} LodePNGBitReader; + +/* data size argument is in bytes. Returns error if size too large causing overflow */ +static unsigned LodePNGBitReader_init(LodePNGBitReader* reader, const unsigned char* data, size_t size) { + size_t temp; + reader->data = data; + reader->size = size; + /* size in bits, return error if overflow (if size_t is 32 bit this supports up to 500MB) */ + if(lodepng_mulofl(size, 8u, &reader->bitsize)) return 105; + /*ensure incremented bp can be compared to bitsize without overflow even when it would be incremented 32 too much and + trying to ensure 32 more bits*/ + if(lodepng_addofl(reader->bitsize, 64u, &temp)) return 105; + reader->bp = 0; + reader->buffer = 0; + return 0; /*ok*/ +} + +/* +ensureBits functions: +Ensures the reader can at least read nbits bits in one or more readBits calls, +safely even if not enough bits are available. +The nbits parameter is unused but is given for documentation purposes, error +checking for amount of bits must be done beforehand. +*/ + +/*See ensureBits documentation above. This one ensures up to 9 bits */ +static LODEPNG_INLINE void ensureBits9(LodePNGBitReader* reader, size_t nbits) { + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if(start + 1u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u); + reader->buffer >>= (reader->bp & 7u); + } else { + reader->buffer = 0; + if(start + 0u < size) reader->buffer = reader->data[start + 0]; + reader->buffer >>= (reader->bp & 7u); + } + (void)nbits; +} + +/*See ensureBits documentation above. This one ensures up to 17 bits */ +static LODEPNG_INLINE void ensureBits17(LodePNGBitReader* reader, size_t nbits) { + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if(start + 2u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | + ((unsigned)reader->data[start + 2] << 16u); + reader->buffer >>= (reader->bp & 7u); + } else { + reader->buffer = 0; + if(start + 0u < size) reader->buffer |= reader->data[start + 0]; + if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + reader->buffer >>= (reader->bp & 7u); + } + (void)nbits; +} + +/*See ensureBits documentation above. This one ensures up to 25 bits */ +static LODEPNG_INLINE void ensureBits25(LodePNGBitReader* reader, size_t nbits) { + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if(start + 3u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | + ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + } else { + reader->buffer = 0; + if(start + 0u < size) reader->buffer |= reader->data[start + 0]; + if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); + reader->buffer >>= (reader->bp & 7u); + } + (void)nbits; +} + +/*See ensureBits documentation above. This one ensures up to 32 bits */ +static LODEPNG_INLINE void ensureBits32(LodePNGBitReader* reader, size_t nbits) { + size_t start = reader->bp >> 3u; + size_t size = reader->size; + if(start + 4u < size) { + reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | + ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + reader->buffer |= (((unsigned)reader->data[start + 4] << 24u) << (8u - (reader->bp & 7u))); + } else { + reader->buffer = 0; + if(start + 0u < size) reader->buffer |= reader->data[start + 0]; + if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); + if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); + if(start + 3u < size) reader->buffer |= ((unsigned)reader->data[start + 3] << 24u); + reader->buffer >>= (reader->bp & 7u); + } + (void)nbits; +} + +/* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits. Max nbits is 31. */ +static LODEPNG_INLINE unsigned peekBits(LodePNGBitReader* reader, size_t nbits) { + /* The shift allows nbits to be only up to 31. */ + return reader->buffer & ((1u << nbits) - 1u); +} + +/* Must have enough bits available with ensureBits */ +static LODEPNG_INLINE void advanceBits(LodePNGBitReader* reader, size_t nbits) { + reader->buffer >>= nbits; + reader->bp += nbits; +} + +/* Must have enough bits available with ensureBits */ +static LODEPNG_INLINE unsigned readBits(LodePNGBitReader* reader, size_t nbits) { + unsigned result = peekBits(reader, nbits); + advanceBits(reader, nbits); + return result; +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +static unsigned reverseBits(unsigned bits, unsigned num) { + /*TODO: implement faster lookup table based version when needed*/ + unsigned i, result = 0; + for(i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i; + return result; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflate - Huffman / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#define FIRST_LENGTH_CODE_INDEX 257 +#define LAST_LENGTH_CODE_INDEX 285 +/*256 literals, the end code, some length codes, and 2 unused codes*/ +#define NUM_DEFLATE_CODE_SYMBOLS 288 +/*the distance codes have their own symbols, 30 used, 2 unused*/ +#define NUM_DISTANCE_SYMBOLS 32 +/*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ +#define NUM_CODE_LENGTH_CODES 19 + +/*the base lengths represented by codes 257-285*/ +static const unsigned LENGTHBASE[29] + = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258}; + +/*the extra bits used by codes 257-285 (added to base length)*/ +static const unsigned LENGTHEXTRA[29] + = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0}; + +/*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ +static const unsigned DISTANCEBASE[30] + = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; + +/*the extra bits of backwards distances (added to base)*/ +static const unsigned DISTANCEEXTRA[30] + = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + +/*the order in which "code length alphabet code lengths" are stored as specified by deflate, out of this the huffman +tree of the dynamic huffman tree lengths is generated*/ +static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] + = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* ////////////////////////////////////////////////////////////////////////// */ + +/* +Huffman tree struct, containing multiple representations of the tree +*/ +typedef struct HuffmanTree { + unsigned* codes; /*the huffman codes (bit patterns representing the symbols)*/ + unsigned* lengths; /*the lengths of the huffman codes*/ + unsigned maxbitlen; /*maximum number of bits a single code can get*/ + unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ + /* for reading only */ + unsigned char* table_len; /*length of symbol from lookup table, or max length if secondary lookup needed*/ + unsigned short* table_value; /*value of symbol from lookup table, or pointer to secondary table if needed*/ +} HuffmanTree; + +static void HuffmanTree_init(HuffmanTree* tree) { + tree->codes = 0; + tree->lengths = 0; + tree->table_len = 0; + tree->table_value = 0; +} + +static void HuffmanTree_cleanup(HuffmanTree* tree) { + lodepng_free(tree->codes); + lodepng_free(tree->lengths); + lodepng_free(tree->table_len); + lodepng_free(tree->table_value); +} + +/* amount of bits for first huffman table lookup (aka root bits), see HuffmanTree_makeTable and huffmanDecodeSymbol.*/ +/* values 8u and 9u work the fastest */ +#define FIRSTBITS 9u + +/* a symbol value too big to represent any valid symbol, to indicate reading disallowed huffman bits combination, +which is possible in case of only 0 or 1 present symbols. */ +#define INVALIDSYMBOL 65535u + +/* make table for huffman decoding */ +static unsigned HuffmanTree_makeTable(HuffmanTree* tree) { + static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/ + static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u; + size_t i, numpresent, pointer, size; /*total table size*/ + unsigned* maxlens = (unsigned*)lodepng_malloc(headsize * sizeof(unsigned)); + if(!maxlens) return 83; /*alloc fail*/ + + /* compute maxlens: max total bit length of symbols sharing prefix in the first table*/ + lodepng_memset(maxlens, 0, headsize * sizeof(*maxlens)); + for(i = 0; i < tree->numcodes; i++) { + unsigned symbol = tree->codes[i]; + unsigned l = tree->lengths[i]; + unsigned index; + if(l <= FIRSTBITS) continue; /*symbols that fit in first table don't increase secondary table size*/ + /*get the FIRSTBITS MSBs, the MSBs of the symbol are encoded first. See later comment about the reversing*/ + index = reverseBits(symbol >> (l - FIRSTBITS), FIRSTBITS); + maxlens[index] = LODEPNG_MAX(maxlens[index], l); + } + /* compute total table size: size of first table plus all secondary tables for symbols longer than FIRSTBITS */ + size = headsize; + for(i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if(l > FIRSTBITS) size += (((size_t)1) << (l - FIRSTBITS)); + } + tree->table_len = (unsigned char*)lodepng_malloc(size * sizeof(*tree->table_len)); + tree->table_value = (unsigned short*)lodepng_malloc(size * sizeof(*tree->table_value)); + if(!tree->table_len || !tree->table_value) { + lodepng_free(maxlens); + /* freeing tree->table values is done at a higher scope */ + return 83; /*alloc fail*/ + } + /*initialize with an invalid length to indicate unused entries*/ + for(i = 0; i < size; ++i) tree->table_len[i] = 16; + + /*fill in the first table for long symbols: max prefix size and pointer to secondary tables*/ + pointer = headsize; + for(i = 0; i < headsize; ++i) { + unsigned l = maxlens[i]; + if(l <= FIRSTBITS) continue; + tree->table_len[i] = l; + tree->table_value[i] = (unsigned short)pointer; + pointer += (((size_t)1) << (l - FIRSTBITS)); + } + lodepng_free(maxlens); + + /*fill in the first table for short symbols, or secondary table for long symbols*/ + numpresent = 0; + for(i = 0; i < tree->numcodes; ++i) { + unsigned l = tree->lengths[i]; + unsigned symbol, reverse; + if(l == 0) continue; + symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ + /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ + reverse = reverseBits(symbol, l); + numpresent++; + + if(l <= FIRSTBITS) { + /*short symbol, fully in first table, replicated num times if l < FIRSTBITS*/ + unsigned num = 1u << (FIRSTBITS - l); + unsigned j; + for(j = 0; j < num; ++j) { + /*bit reader will read the l bits of symbol first, the remaining FIRSTBITS - l bits go to the MSB's*/ + unsigned index = reverse | (j << l); + if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + tree->table_len[index] = l; + tree->table_value[index] = (unsigned short)i; + } + } else { + /*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/ + /*the FIRSTBITS MSBs of the symbol are the first table index*/ + unsigned index = reverse & mask; + unsigned maxlen = tree->table_len[index]; + /*log2 of secondary table length, should be >= l - FIRSTBITS*/ + unsigned tablelen = maxlen - FIRSTBITS; + unsigned start = tree->table_value[index]; /*starting index in secondary table*/ + unsigned num = 1u << (tablelen - (l - FIRSTBITS)); /*amount of entries of this symbol in secondary table*/ + unsigned j; + if(maxlen < l) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ + for(j = 0; j < num; ++j) { + unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */ + unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS))); + tree->table_len[index2] = l; + tree->table_value[index2] = (unsigned short)i; + } + } + } + + if(numpresent < 2) { + /* In case of exactly 1 symbol, in theory the huffman symbol needs 0 bits, + but deflate uses 1 bit instead. In case of 0 symbols, no symbols can + appear at all, but such huffman tree could still exist (e.g. if distance + codes are never used). In both cases, not all symbols of the table will be + filled in. Fill them in with an invalid symbol value so returning them from + huffmanDecodeSymbol will cause error. */ + for(i = 0; i < size; ++i) { + if(tree->table_len[i] == 16) { + /* As length, use a value smaller than FIRSTBITS for the head table, + and a value larger than FIRSTBITS for the secondary table, to ensure + valid behavior for advanceBits when reading this symbol. */ + tree->table_len[i] = (i < headsize) ? 1 : (FIRSTBITS + 1); + tree->table_value[i] = INVALIDSYMBOL; + } + } + } else { + /* A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. + If that is not the case (due to too long length codes), the table will not + have been fully used, and this is an error (not all bit combinations can be + decoded): an oversubscribed huffman tree, indicated by error 55. */ + for(i = 0; i < size; ++i) { + if(tree->table_len[i] == 16) return 55; + } + } + + return 0; +} + +/* +Second step for the ...makeFromLengths and ...makeFromFrequencies functions. +numcodes, lengths and maxbitlen must already be filled in correctly. return +value is error. +*/ +static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { + unsigned* blcount; + unsigned* nextcode; + unsigned error = 0; + unsigned bits, n; + + tree->codes = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); + blcount = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + nextcode = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); + if(!tree->codes || !blcount || !nextcode) error = 83; /*alloc fail*/ + + if(!error) { + for(n = 0; n != tree->maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0; + /*step 1: count number of instances of each code length*/ + for(bits = 0; bits != tree->numcodes; ++bits) ++blcount[tree->lengths[bits]]; + /*step 2: generate the nextcode values*/ + for(bits = 1; bits <= tree->maxbitlen; ++bits) { + nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1u; + } + /*step 3: generate all the codes*/ + for(n = 0; n != tree->numcodes; ++n) { + if(tree->lengths[n] != 0) { + tree->codes[n] = nextcode[tree->lengths[n]]++; + /*remove superfluous bits from the code*/ + tree->codes[n] &= ((1u << tree->lengths[n]) - 1u); + } + } + } + + lodepng_free(blcount); + lodepng_free(nextcode); + + if(!error) error = HuffmanTree_makeTable(tree); + return error; +} + +/* +given the code lengths (as stored in the PNG file), generate the tree as defined +by Deflate. maxbitlen is the maximum bits that a code in the tree can have. +return value is error. +*/ +static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, + size_t numcodes, unsigned maxbitlen) { + unsigned i; + tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->maxbitlen = maxbitlen; + return HuffmanTree_makeFromLengths2(tree); +} + +#ifdef LODEPNG_COMPILE_ENCODER + +/*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", +Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ + +/*chain node for boundary package merge*/ +typedef struct BPMNode { + int weight; /*the sum of all weights in this chain*/ + unsigned index; /*index of this leaf node (called "count" in the paper)*/ + struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ + int in_use; +} BPMNode; + +/*lists of chains*/ +typedef struct BPMLists { + /*memory pool*/ + unsigned memsize; + BPMNode* memory; + unsigned numfree; + unsigned nextfree; + BPMNode** freelist; + /*two heads of lookahead chains per list*/ + unsigned listsize; + BPMNode** chains0; + BPMNode** chains1; +} BPMLists; + +/*creates a new chain node with the given parameters, from the memory in the lists */ +static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { + unsigned i; + BPMNode* result; + + /*memory full, so garbage collect*/ + if(lists->nextfree >= lists->numfree) { + /*mark only those that are in use*/ + for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; + for(i = 0; i != lists->listsize; ++i) { + BPMNode* node; + for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; + for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; + } + /*collect those that are free*/ + lists->numfree = 0; + for(i = 0; i != lists->memsize; ++i) { + if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; + } + lists->nextfree = 0; + } + + result = lists->freelist[lists->nextfree++]; + result->weight = weight; + result->index = index; + result->tail = tail; + return result; +} + +/*sort the leaves with stable mergesort*/ +static void bpmnode_sort(BPMNode* leaves, size_t num) { + BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); + size_t width, counter = 0; + for(width = 1; width < num; width *= 2) { + BPMNode* a = (counter & 1) ? mem : leaves; + BPMNode* b = (counter & 1) ? leaves : mem; + size_t p; + for(p = 0; p < num; p += 2 * width) { + size_t q = (p + width > num) ? num : (p + width); + size_t r = (p + 2 * width > num) ? num : (p + 2 * width); + size_t i = p, j = q, k; + for(k = p; k < r; k++) { + if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; + else b[k] = a[j++]; + } + } + counter++; + } + if(counter & 1) lodepng_memcpy(leaves, mem, sizeof(*leaves) * num); + lodepng_free(mem); +} + +/*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ +static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) { + unsigned lastindex = lists->chains1[c]->index; + + if(c == 0) { + if(lastindex >= numpresent) return; + lists->chains0[c] = lists->chains1[c]; + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); + } else { + /*sum of the weights of the head nodes of the previous lookahead chains.*/ + int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; + lists->chains0[c] = lists->chains1[c]; + if(lastindex < numpresent && sum > leaves[lastindex].weight) { + lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); + return; + } + lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); + /*in the end we are only interested in the chain of the last list, so no + need to recurse if we're at the last one (this gives measurable speedup)*/ + if(num + 1 < (int)(2 * numpresent - 2)) { + boundaryPM(lists, leaves, numpresent, c - 1, num); + boundaryPM(lists, leaves, numpresent, c - 1, num); + } + } +} + +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen) { + unsigned error = 0; + unsigned i; + size_t numpresent = 0; /*number of symbols with non-zero frequency*/ + BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ + + if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/ + + leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); + if(!leaves) return 83; /*alloc fail*/ + + for(i = 0; i != numcodes; ++i) { + if(frequencies[i] > 0) { + leaves[numpresent].weight = (int)frequencies[i]; + leaves[numpresent].index = i; + ++numpresent; + } + } + + lodepng_memset(lengths, 0, numcodes * sizeof(*lengths)); + + /*ensure at least two present symbols. There should be at least one symbol + according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To + make these work as well ensure there are at least two symbols. The + Package-Merge code below also doesn't work correctly if there's only one + symbol, it'd give it the theoretical 0 bits but in practice zlib wants 1 bit*/ + if(numpresent == 0) { + lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ + } else if(numpresent == 1) { + lengths[leaves[0].index] = 1; + lengths[leaves[0].index == 0 ? 1 : 0] = 1; + } else { + BPMLists lists; + BPMNode* node; + + bpmnode_sort(leaves, numpresent); + + lists.listsize = maxbitlen; + lists.memsize = 2 * maxbitlen * (maxbitlen + 1); + lists.nextfree = 0; + lists.numfree = lists.memsize; + lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); + lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); + lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); + if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ + + if(!error) { + for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; + + bpmnode_create(&lists, leaves[0].weight, 1, 0); + bpmnode_create(&lists, leaves[1].weight, 2, 0); + + for(i = 0; i != lists.listsize; ++i) { + lists.chains0[i] = &lists.memory[0]; + lists.chains1[i] = &lists.memory[1]; + } + + /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ + for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); + + for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) { + for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; + } + } + + lodepng_free(lists.memory); + lodepng_free(lists.freelist); + lodepng_free(lists.chains0); + lodepng_free(lists.chains1); + } + + lodepng_free(leaves); + return error; +} + +/*Create the Huffman tree given the symbol frequencies*/ +static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, + size_t mincodes, size_t numcodes, unsigned maxbitlen) { + unsigned error = 0; + while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ + tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); + if(!tree->lengths) return 83; /*alloc fail*/ + tree->maxbitlen = maxbitlen; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + + error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); + if(!error) error = HuffmanTree_makeFromLengths2(tree); + return error; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ +static unsigned generateFixedLitLenTree(HuffmanTree* tree) { + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ + for(i = 0; i <= 143; ++i) bitlen[i] = 8; + for(i = 144; i <= 255; ++i) bitlen[i] = 9; + for(i = 256; i <= 279; ++i) bitlen[i] = 7; + for(i = 280; i <= 287; ++i) bitlen[i] = 8; + + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +/*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ +static unsigned generateFixedDistanceTree(HuffmanTree* tree) { + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen) return 83; /*alloc fail*/ + + /*there are 32 distance codes, but 30-31 are unused*/ + for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); + + lodepng_free(bitlen); + return error; +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* +returns the code. The bit reader must already have been ensured at least 15 bits +*/ +static unsigned huffmanDecodeSymbol(LodePNGBitReader* reader, const HuffmanTree* codetree) { + unsigned short code = peekBits(reader, FIRSTBITS); + unsigned short l = codetree->table_len[code]; + unsigned short value = codetree->table_value[code]; + if(l <= FIRSTBITS) { + advanceBits(reader, l); + return value; + } else { + advanceBits(reader, FIRSTBITS); + value += peekBits(reader, l - FIRSTBITS); + advanceBits(reader, codetree->table_len[value] - FIRSTBITS); + return codetree->table_value[value]; + } +} +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Inflator (Decompressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*get the tree of a deflated block with fixed tree, as specified in the deflate specification +Returns error code.*/ +static unsigned getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { + unsigned error = generateFixedLitLenTree(tree_ll); + if(error) return error; + return generateFixedDistanceTree(tree_d); +} + +/*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ +static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, + LodePNGBitReader* reader) { + /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ + unsigned error = 0; + unsigned n, HLIT, HDIST, HCLEN, i; + + /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ + unsigned* bitlen_ll = 0; /*lit,len code lengths*/ + unsigned* bitlen_d = 0; /*dist code lengths*/ + /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ + unsigned* bitlen_cl = 0; + HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ + + if(reader->bitsize - reader->bp < 14) return 49; /*error: the bit pointer is or will go past the memory*/ + ensureBits17(reader, 14); + + /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ + HLIT = readBits(reader, 5) + 257; + /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ + HDIST = readBits(reader, 5) + 1; + /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ + HCLEN = readBits(reader, 4) + 4; + + bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); + if(!bitlen_cl) return 83 /*alloc fail*/; + + HuffmanTree_init(&tree_cl); + + while(!error) { + /*read the code length codes out of 3 * (amount of code length codes) bits*/ + if(lodepng_gtofl(reader->bp, HCLEN * 3, reader->bitsize)) { + ERROR_BREAK(50); /*error: the bit pointer is or will go past the memory*/ + } + for(i = 0; i != HCLEN; ++i) { + ensureBits9(reader, 3); /*out of bounds already checked above */ + bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3); + } + for(i = HCLEN; i != NUM_CODE_LENGTH_CODES; ++i) { + bitlen_cl[CLCL_ORDER[i]] = 0; + } + + error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); + if(error) break; + + /*now we can use this tree to read the lengths for the tree that this function will return*/ + bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); + lodepng_memset(bitlen_ll, 0, NUM_DEFLATE_CODE_SYMBOLS * sizeof(*bitlen_ll)); + lodepng_memset(bitlen_d, 0, NUM_DISTANCE_SYMBOLS * sizeof(*bitlen_d)); + + /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ + i = 0; + while(i < HLIT + HDIST) { + unsigned code; + ensureBits25(reader, 22); /* up to 15 bits for huffman code, up to 7 extra bits below*/ + code = huffmanDecodeSymbol(reader, &tree_cl); + if(code <= 15) /*a length code*/ { + if(i < HLIT) bitlen_ll[i] = code; + else bitlen_d[i - HLIT] = code; + ++i; + } else if(code == 16) /*repeat previous*/ { + unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ + unsigned value; /*set value to the previous code*/ + + if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + + replength += readBits(reader, 2); + + if(i < HLIT + 1) value = bitlen_ll[i - 1]; + else value = bitlen_d[i - HLIT - 1]; + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ + if(i < HLIT) bitlen_ll[i] = value; + else bitlen_d[i - HLIT] = value; + ++i; + } + } else if(code == 17) /*repeat "0" 3-10 times*/ { + unsigned replength = 3; /*read in the bits that indicate repeat length*/ + replength += readBits(reader, 3); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else if(code == 18) /*repeat "0" 11-138 times*/ { + unsigned replength = 11; /*read in the bits that indicate repeat length*/ + replength += readBits(reader, 7); + + /*repeat this value in the next lengths*/ + for(n = 0; n < replength; ++n) { + if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ + + if(i < HLIT) bitlen_ll[i] = 0; + else bitlen_d[i - HLIT] = 0; + ++i; + } + } else /*if(code == INVALIDSYMBOL)*/ { + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + /*check if any of the ensureBits above went out of bounds*/ + if(reader->bp > reader->bitsize) { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ + ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + } + } + if(error) break; + + if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ + + /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ + error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); + if(error) break; + error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); + + break; /*end of error-while*/ + } + + lodepng_free(bitlen_cl); + lodepng_free(bitlen_ll); + lodepng_free(bitlen_d); + HuffmanTree_cleanup(&tree_cl); + + return error; +} + +/*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/ +static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader, + unsigned btype, size_t max_output_size) { + unsigned error = 0; + HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ + HuffmanTree tree_d; /*the huffman tree for distance codes*/ + const size_t reserved_size = 260; /* must be at least 258 for max length, and a few extra for adding a few extra literals */ + int done = 0; + + if(!ucvector_reserve(out, out->size + reserved_size)) return 83; /*alloc fail*/ + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d); + else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); + + + while(!error && !done) /*decode all symbols until end reached, breaks at end code*/ { + /*code_ll is literal, length or end code*/ + unsigned code_ll; + /* ensure enough bits for 2 huffman code reads (15 bits each): if the first is a literal, a second literal is read at once. This + appears to be slightly faster, than ensuring 20 bits here for 1 huffman symbol and the potential 5 extra bits for the length symbol.*/ + ensureBits32(reader, 30); + code_ll = huffmanDecodeSymbol(reader, &tree_ll); + if(code_ll <= 255) { + /*slightly faster code path if multiple literals in a row*/ + out->data[out->size++] = (unsigned char)code_ll; + code_ll = huffmanDecodeSymbol(reader, &tree_ll); + } + if(code_ll <= 255) /*literal symbol*/ { + out->data[out->size++] = (unsigned char)code_ll; + } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { + unsigned code_d, distance; + unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ + size_t start, backward, length; + + /*part 1: get length base*/ + length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; + + /*part 2: get extra bits and add the value of that to length*/ + numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; + if(numextrabits_l != 0) { + /* bits already ensured above */ + ensureBits25(reader, 5); + length += readBits(reader, numextrabits_l); + } + + /*part 3: get distance code*/ + ensureBits32(reader, 28); /* up to 15 for the huffman symbol, up to 13 for the extra bits */ + code_d = huffmanDecodeSymbol(reader, &tree_d); + if(code_d > 29) { + if(code_d <= 31) { + ERROR_BREAK(18); /*error: invalid distance code (30-31 are never used)*/ + } else /* if(code_d == INVALIDSYMBOL) */{ + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + } + distance = DISTANCEBASE[code_d]; + + /*part 4: get extra bits from distance*/ + numextrabits_d = DISTANCEEXTRA[code_d]; + if(numextrabits_d != 0) { + /* bits already ensured above */ + distance += readBits(reader, numextrabits_d); + } + + /*part 5: fill in all the out[n] values based on the length and dist*/ + start = out->size; + if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ + backward = start - distance; + + out->size += length; + if(distance < length) { + size_t forward; + lodepng_memcpy(out->data + start, out->data + backward, distance); + start += distance; + for(forward = distance; forward < length; ++forward) { + out->data[start++] = out->data[backward++]; + } + } else { + lodepng_memcpy(out->data + start, out->data + backward, length); + } + } else if(code_ll == 256) { + done = 1; /*end code, finish the loop*/ + } else /*if(code_ll == INVALIDSYMBOL)*/ { + ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ + } + if(out->allocsize - out->size < reserved_size) { + if(!ucvector_reserve(out, out->size + reserved_size)) ERROR_BREAK(83); /*alloc fail*/ + } + /*check if any of the ensureBits above went out of bounds*/ + if(reader->bp > reader->bitsize) { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + (10=no endcode, 11=wrong jump outside of tree)*/ + /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ + ERROR_BREAK(51); /*error, bit pointer jumps past memory*/ + } + if(max_output_size && out->size > max_output_size) { + ERROR_BREAK(109); /*error, larger than max size*/ + } + } + + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned inflateNoCompression(ucvector* out, LodePNGBitReader* reader, + const LodePNGDecompressSettings* settings) { + size_t bytepos; + size_t size = reader->size; + unsigned LEN, NLEN, error = 0; + + /*go to first boundary of byte*/ + bytepos = (reader->bp + 7u) >> 3u; + + /*read LEN (2 bytes) and NLEN (2 bytes)*/ + if(bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/ + LEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; + NLEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; + + /*check if 16-bit NLEN is really the one's complement of LEN*/ + if(!settings->ignore_nlen && LEN + NLEN != 65535) { + return 21; /*error: NLEN is not one's complement of LEN*/ + } + + if(!ucvector_resize(out, out->size + LEN)) return 83; /*alloc fail*/ + + /*read the literal data: LEN bytes are now stored in the out buffer*/ + if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/ + + /*out->data can be NULL (when LEN is zero), and arithmetics on NULL ptr is undefined*/ + if (LEN) { + lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN); + bytepos += LEN; + } + + reader->bp = bytepos << 3u; + + return error; +} + +static unsigned lodepng_inflatev(ucvector* out, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + unsigned BFINAL = 0; + LodePNGBitReader reader; + unsigned error = LodePNGBitReader_init(&reader, in, insize); + + if(error) return error; + + while(!BFINAL) { + unsigned BTYPE; + if(reader.bitsize - reader.bp < 3) return 52; /*error, bit pointer will jump past memory*/ + ensureBits9(&reader, 3); + BFINAL = readBits(&reader, 1); + BTYPE = readBits(&reader, 2); + + if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ + else if(BTYPE == 0) error = inflateNoCompression(out, &reader, settings); /*no compression*/ + else error = inflateHuffmanBlock(out, &reader, BTYPE, settings->max_output_size); /*compression, BTYPE 01 or 10*/ + if(!error && settings->max_output_size && out->size > settings->max_output_size) error = 109; + if(error) break; + } + + return error; +} + +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + ucvector v = ucvector_init(*out, *outsize); + unsigned error = lodepng_inflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned inflatev(ucvector* out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + if(settings->custom_inflate) { + unsigned error = settings->custom_inflate(&out->data, &out->size, in, insize, settings); + out->allocsize = out->size; + if(error) { + /*the custom inflate is allowed to have its own error codes, however, we translate it to code 110*/ + error = 110; + /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/ + if(settings->max_output_size && out->size > settings->max_output_size) error = 109; + } + return error; + } else { + return lodepng_inflatev(out, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Deflator (Compressor) / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static const unsigned MAX_SUPPORTED_DEFLATE_LENGTH = 258; + +/*search the index in the array, that has the largest value smaller than or equal to the given value, +given array must be sorted (if no value is smaller, it returns the size of the given array)*/ +static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { + /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ + size_t left = 1; + size_t right = array_size - 1; + + while(left <= right) { + size_t mid = (left + right) >> 1; + if(array[mid] >= value) right = mid - 1; + else left = mid + 1; + } + if(left >= array_size || array[left] > value) left--; + return left; +} + +static void addLengthDistance(uivector* values, size_t length, size_t distance) { + /*values in encoded vector are those used by deflate: + 0-255: literal bytes + 256: end + 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) + 286-287: invalid*/ + + unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); + unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); + unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); + unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); + + size_t pos = values->size; + /*TODO: return error when this fails (out of memory)*/ + unsigned ok = uivector_resize(values, values->size + 4); + if(ok) { + values->data[pos + 0] = length_code + FIRST_LENGTH_CODE_INDEX; + values->data[pos + 1] = extra_length; + values->data[pos + 2] = dist_code; + values->data[pos + 3] = extra_distance; + } +} + +/*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 +bytes as input because 3 is the minimum match length for deflate*/ +static const unsigned HASH_NUM_VALUES = 65536; +static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ + +typedef struct Hash { + int* head; /*hash value to head circular pos - can be outdated if went around window*/ + /*circular pos to prev circular pos*/ + unsigned short* chain; + int* val; /*circular pos to hash value*/ + + /*TODO: do this not only for zeros but for any repeated byte. However for PNG + it's always going to be the zeros that dominate, so not important for PNG*/ + int* headz; /*similar to head, but for chainz*/ + unsigned short* chainz; /*those with same amount of zeros*/ + unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ +} Hash; + +static unsigned hash_init(Hash* hash, unsigned windowsize) { + unsigned i; + hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); + hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); + hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); + hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + + if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) { + return 83; /*alloc fail*/ + } + + /*initialize hash table*/ + for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; + for(i = 0; i != windowsize; ++i) hash->val[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ + + for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; + for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ + + return 0; +} + +static void hash_cleanup(Hash* hash) { + lodepng_free(hash->head); + lodepng_free(hash->val); + lodepng_free(hash->chain); + + lodepng_free(hash->zeros); + lodepng_free(hash->headz); + lodepng_free(hash->chainz); +} + + + +static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { + unsigned result = 0; + if(pos + 2 < size) { + /*A simple shift and xor hash is used. Since the data of PNGs is dominated + by zeroes due to the filters, a better hash does not have a significant + effect on speed in traversing the chain, and causes more time spend on + calculating the hash.*/ + result ^= ((unsigned)data[pos + 0] << 0u); + result ^= ((unsigned)data[pos + 1] << 4u); + result ^= ((unsigned)data[pos + 2] << 8u); + } else { + size_t amount, i; + if(pos >= size) return 0; + amount = size - pos; + for(i = 0; i != amount; ++i) result ^= ((unsigned)data[pos + i] << (i * 8u)); + } + return result & HASH_BIT_MASK; +} + +static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) { + const unsigned char* start = data + pos; + const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; + if(end > data + size) end = data + size; + data = start; + while(data != end && *data == 0) ++data; + /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ + return (unsigned)(data - start); +} + +/*wpos = pos & (windowsize - 1)*/ +static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) { + hash->val[wpos] = (int)hashval; + if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; + hash->head[hashval] = (int)wpos; + + hash->zeros[wpos] = numzeros; + if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; + hash->headz[numzeros] = (int)wpos; +} + +/* +LZ77-encode the data. Return value is error code. The input are raw bytes, the output +is in the form of unsigned integers with codes representing for example literal bytes, or +length/distance pairs. +It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a +sliding window (of windowsize) is used, and all past bytes in that window can be used as +the "dictionary". A brute force search through all possible distances would be slow, and +this hash technique is one out of several ways to speed this up. +*/ +static unsigned encodeLZ77(uivector* out, Hash* hash, + const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, + unsigned minmatch, unsigned nicematch, unsigned lazymatching) { + size_t pos; + unsigned i, error = 0; + /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ + unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u; + unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; + + unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ + unsigned numzeros = 0; + + unsigned offset; /*the offset represents the distance in LZ77 terminology*/ + unsigned length; + unsigned lazy = 0; + unsigned lazylength = 0, lazyoffset = 0; + unsigned hashval; + unsigned current_offset, current_length; + unsigned prev_offset; + const unsigned char *lastptr, *foreptr, *backptr; + unsigned hashpos; + + if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ + if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ + + if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; + + for(pos = inpos; pos < insize; ++pos) { + size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ + unsigned chainlength = 0; + + hashval = getHash(in, insize, pos); + + if(usezeros && hashval == 0) { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } else { + numzeros = 0; + } + + updateHashChain(hash, wpos, hashval, numzeros); + + /*the length and offset found for the current position*/ + length = 0; + offset = 0; + + hashpos = hash->chain[wpos]; + + lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; + + /*search for the longest string*/ + prev_offset = 0; + for(;;) { + if(chainlength++ >= maxchainlength) break; + current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize); + + if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ + prev_offset = current_offset; + if(current_offset > 0) { + /*test the next characters*/ + foreptr = &in[pos]; + backptr = &in[pos - current_offset]; + + /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ + if(numzeros >= 3) { + unsigned skip = hash->zeros[hashpos]; + if(skip > numzeros) skip = numzeros; + backptr += skip; + foreptr += skip; + } + + while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ { + ++backptr; + ++foreptr; + } + current_length = (unsigned)(foreptr - &in[pos]); + + if(current_length > length) { + length = current_length; /*the longest length*/ + offset = current_offset; /*the offset that is related to this longest length*/ + /*jump out once a length of max length is found (speed gain). This also jumps + out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ + if(current_length >= nicematch) break; + } + } + + if(hashpos == hash->chain[hashpos]) break; + + if(numzeros >= 3 && length > numzeros) { + hashpos = hash->chainz[hashpos]; + if(hash->zeros[hashpos] != numzeros) break; + } else { + hashpos = hash->chain[hashpos]; + /*outdated hash value, happens if particular value was not encountered in whole last window*/ + if(hash->val[hashpos] != (int)hashval) break; + } + } + + if(lazymatching) { + if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) { + lazy = 1; + lazylength = length; + lazyoffset = offset; + continue; /*try the next byte*/ + } + if(lazy) { + lazy = 0; + if(pos == 0) ERROR_BREAK(81); + if(length > lazylength + 1) { + /*push the previous character as literal*/ + if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); + } else { + length = lazylength; + offset = lazyoffset; + hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ + hash->headz[numzeros] = -1; /*idem*/ + --pos; + } + } + } + if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); + + /*encode it as length/distance pair or literal value*/ + if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ { + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } else if(length < minmatch || (length == 3 && offset > 4096)) { + /*compensate for the fact that longer offsets have more extra bits, a + length of only 3 may be not worth it then*/ + if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } else { + addLengthDistance(out, length, offset); + for(i = 1; i < length; ++i) { + ++pos; + wpos = pos & (windowsize - 1); + hashval = getHash(in, insize, pos); + if(usezeros && hashval == 0) { + if(numzeros == 0) numzeros = countZeros(in, insize, pos); + else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; + } else { + numzeros = 0; + } + updateHashChain(hash, wpos, hashval, numzeros); + } + } + } /*end of the loop through each character of input*/ + + return error; +} + +/* /////////////////////////////////////////////////////////////////////////// */ + +static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) { + /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, + 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ + + size_t i, numdeflateblocks = (datasize + 65534u) / 65535u; + size_t datapos = 0; + for(i = 0; i != numdeflateblocks; ++i) { + unsigned BFINAL, BTYPE, LEN, NLEN; + unsigned char firstbyte; + size_t pos = out->size; + + BFINAL = (i == numdeflateblocks - 1); + BTYPE = 0; + + LEN = 65535; + if(datasize - datapos < 65535u) LEN = (unsigned)datasize - (unsigned)datapos; + NLEN = 65535 - LEN; + + if(!ucvector_resize(out, out->size + LEN + 5)) return 83; /*alloc fail*/ + + firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1u) << 1u) + ((BTYPE & 2u) << 1u)); + out->data[pos + 0] = firstbyte; + out->data[pos + 1] = (unsigned char)(LEN & 255); + out->data[pos + 2] = (unsigned char)(LEN >> 8u); + out->data[pos + 3] = (unsigned char)(NLEN & 255); + out->data[pos + 4] = (unsigned char)(NLEN >> 8u); + lodepng_memcpy(out->data + pos + 5, data + datapos, LEN); + datapos += LEN; + } + + return 0; +} + +/* +write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. +tree_ll: the tree for lit and len codes. +tree_d: the tree for distance codes. +*/ +static void writeLZ77data(LodePNGBitWriter* writer, const uivector* lz77_encoded, + const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { + size_t i = 0; + for(i = 0; i != lz77_encoded->size; ++i) { + unsigned val = lz77_encoded->data[i]; + writeBitsReversed(writer, tree_ll->codes[val], tree_ll->lengths[val]); + if(val > 256) /*for a length code, 3 more things have to be added*/ { + unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; + unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; + unsigned length_extra_bits = lz77_encoded->data[++i]; + + unsigned distance_code = lz77_encoded->data[++i]; + + unsigned distance_index = distance_code; + unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; + unsigned distance_extra_bits = lz77_encoded->data[++i]; + + writeBits(writer, length_extra_bits, n_length_extra_bits); + writeBitsReversed(writer, tree_d->codes[distance_code], tree_d->lengths[distance_code]); + writeBits(writer, distance_extra_bits, n_distance_extra_bits); + } + } +} + +/*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ +static unsigned deflateDynamic(LodePNGBitWriter* writer, Hash* hash, + const unsigned char* data, size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { + unsigned error = 0; + + /* + A block is compressed as follows: The PNG data is lz77 encoded, resulting in + literal bytes and length/distance pairs. This is then huffman compressed with + two huffman trees. One huffman tree is used for the lit and len values ("ll"), + another huffman tree is used for the dist values ("d"). These two trees are + stored using their code lengths, and to compress even more these code lengths + are also run-length encoded and huffman compressed. This gives a huffman tree + of code lengths "cl". The code lengths used to describe this third tree are + the code length code lengths ("clcl"). + */ + + /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ + uivector lz77_encoded; + HuffmanTree tree_ll; /*tree for lit,len values*/ + HuffmanTree tree_d; /*tree for distance codes*/ + HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ + unsigned* frequencies_ll = 0; /*frequency of lit,len codes*/ + unsigned* frequencies_d = 0; /*frequency of dist codes*/ + unsigned* frequencies_cl = 0; /*frequency of code length codes*/ + unsigned* bitlen_lld = 0; /*lit,len,dist code lengths (int bits), literally (without repeat codes).*/ + unsigned* bitlen_lld_e = 0; /*bitlen_lld encoded with repeat codes (this is a rudimentary run length compression)*/ + size_t datasize = dataend - datapos; + + /* + If we could call "bitlen_cl" the the code length code lengths ("clcl"), that is the bit lengths of codes to represent + tree_cl in CLCL_ORDER, then due to the huffman compression of huffman tree representations ("two levels"), there are + some analogies: + bitlen_lld is to tree_cl what data is to tree_ll and tree_d. + bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. + bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. + */ + + unsigned BFINAL = final; + size_t i; + size_t numcodes_ll, numcodes_d, numcodes_lld, numcodes_lld_e, numcodes_cl; + unsigned HLIT, HDIST, HCLEN; + + uivector_init(&lz77_encoded); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_cl); + /* could fit on stack, but >1KB is on the larger side so allocate instead */ + frequencies_ll = (unsigned*)lodepng_malloc(286 * sizeof(*frequencies_ll)); + frequencies_d = (unsigned*)lodepng_malloc(30 * sizeof(*frequencies_d)); + frequencies_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl)); + + if(!frequencies_ll || !frequencies_d || !frequencies_cl) error = 83; /*alloc fail*/ + + /*This while loop never loops due to a break at the end, it is here to + allow breaking out of it to the cleanup phase on error conditions.*/ + while(!error) { + lodepng_memset(frequencies_ll, 0, 286 * sizeof(*frequencies_ll)); + lodepng_memset(frequencies_d, 0, 30 * sizeof(*frequencies_d)); + lodepng_memset(frequencies_cl, 0, NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl)); + + if(settings->use_lz77) { + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(error) break; + } else { + if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); + for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + } + + /*Count the frequencies of lit, len and dist codes*/ + for(i = 0; i != lz77_encoded.size; ++i) { + unsigned symbol = lz77_encoded.data[i]; + ++frequencies_ll[symbol]; + if(symbol > 256) { + unsigned dist = lz77_encoded.data[i + 2]; + ++frequencies_d[dist]; + i += 3; + } + } + frequencies_ll[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ + + /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ + error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll, 257, 286, 15); + if(error) break; + /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ + error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d, 2, 30, 15); + if(error) break; + + numcodes_ll = LODEPNG_MIN(tree_ll.numcodes, 286); + numcodes_d = LODEPNG_MIN(tree_d.numcodes, 30); + /*store the code lengths of both generated trees in bitlen_lld*/ + numcodes_lld = numcodes_ll + numcodes_d; + bitlen_lld = (unsigned*)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld)); + /*numcodes_lld_e never needs more size than bitlen_lld*/ + bitlen_lld_e = (unsigned*)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld_e)); + if(!bitlen_lld || !bitlen_lld_e) ERROR_BREAK(83); /*alloc fail*/ + numcodes_lld_e = 0; + + for(i = 0; i != numcodes_ll; ++i) bitlen_lld[i] = tree_ll.lengths[i]; + for(i = 0; i != numcodes_d; ++i) bitlen_lld[numcodes_ll + i] = tree_d.lengths[i]; + + /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), + 17 (3-10 zeroes), 18 (11-138 zeroes)*/ + for(i = 0; i != numcodes_lld; ++i) { + unsigned j = 0; /*amount of repetitions*/ + while(i + j + 1 < numcodes_lld && bitlen_lld[i + j + 1] == bitlen_lld[i]) ++j; + + if(bitlen_lld[i] == 0 && j >= 2) /*repeat code for zeroes*/ { + ++j; /*include the first zero*/ + if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ { + bitlen_lld_e[numcodes_lld_e++] = 17; + bitlen_lld_e[numcodes_lld_e++] = j - 3; + } else /*repeat code 18 supports max 138 zeroes*/ { + if(j > 138) j = 138; + bitlen_lld_e[numcodes_lld_e++] = 18; + bitlen_lld_e[numcodes_lld_e++] = j - 11; + } + i += (j - 1); + } else if(j >= 3) /*repeat code for value other than zero*/ { + size_t k; + unsigned num = j / 6u, rest = j % 6u; + bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i]; + for(k = 0; k < num; ++k) { + bitlen_lld_e[numcodes_lld_e++] = 16; + bitlen_lld_e[numcodes_lld_e++] = 6 - 3; + } + if(rest >= 3) { + bitlen_lld_e[numcodes_lld_e++] = 16; + bitlen_lld_e[numcodes_lld_e++] = rest - 3; + } + else j -= rest; + i += j; + } else /*too short to benefit from repeat code*/ { + bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i]; + } + } + + /*generate tree_cl, the huffmantree of huffmantrees*/ + for(i = 0; i != numcodes_lld_e; ++i) { + ++frequencies_cl[bitlen_lld_e[i]]; + /*after a repeat code come the bits that specify the number of repetitions, + those don't need to be in the frequencies_cl calculation*/ + if(bitlen_lld_e[i] >= 16) ++i; + } + + error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl, + NUM_CODE_LENGTH_CODES, NUM_CODE_LENGTH_CODES, 7); + if(error) break; + + /*compute amount of code-length-code-lengths to output*/ + numcodes_cl = NUM_CODE_LENGTH_CODES; + /*trim zeros at the end (using CLCL_ORDER), but minimum size must be 4 (see HCLEN below)*/ + while(numcodes_cl > 4u && tree_cl.lengths[CLCL_ORDER[numcodes_cl - 1u]] == 0) { + numcodes_cl--; + } + + /* + Write everything into the output + + After the BFINAL and BTYPE, the dynamic block consists out of the following: + - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN + - (HCLEN+4)*3 bits code lengths of code length alphabet + - HLIT + 257 code lengths of lit/length alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - HDIST + 1 code lengths of distance alphabet (encoded using the code length + alphabet, + possible repetition codes 16, 17, 18) + - compressed data + - 256 (end code) + */ + + /*Write block type*/ + writeBits(writer, BFINAL, 1); + writeBits(writer, 0, 1); /*first bit of BTYPE "dynamic"*/ + writeBits(writer, 1, 1); /*second bit of BTYPE "dynamic"*/ + + /*write the HLIT, HDIST and HCLEN values*/ + /*all three sizes take trimmed ending zeroes into account, done either by HuffmanTree_makeFromFrequencies + or in the loop for numcodes_cl above, which saves space. */ + HLIT = (unsigned)(numcodes_ll - 257); + HDIST = (unsigned)(numcodes_d - 1); + HCLEN = (unsigned)(numcodes_cl - 4); + writeBits(writer, HLIT, 5); + writeBits(writer, HDIST, 5); + writeBits(writer, HCLEN, 4); + + /*write the code lengths of the code length alphabet ("bitlen_cl")*/ + for(i = 0; i != numcodes_cl; ++i) writeBits(writer, tree_cl.lengths[CLCL_ORDER[i]], 3); + + /*write the lengths of the lit/len AND the dist alphabet*/ + for(i = 0; i != numcodes_lld_e; ++i) { + writeBitsReversed(writer, tree_cl.codes[bitlen_lld_e[i]], tree_cl.lengths[bitlen_lld_e[i]]); + /*extra bits of repeat codes*/ + if(bitlen_lld_e[i] == 16) writeBits(writer, bitlen_lld_e[++i], 2); + else if(bitlen_lld_e[i] == 17) writeBits(writer, bitlen_lld_e[++i], 3); + else if(bitlen_lld_e[i] == 18) writeBits(writer, bitlen_lld_e[++i], 7); + } + + /*write the compressed data symbols*/ + writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); + /*error: the length of the end code 256 must be larger than 0*/ + if(tree_ll.lengths[256] == 0) ERROR_BREAK(64); + + /*write the end code*/ + writeBitsReversed(writer, tree_ll.codes[256], tree_ll.lengths[256]); + + break; /*end of error-while*/ + } + + /*cleanup*/ + uivector_cleanup(&lz77_encoded); + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + HuffmanTree_cleanup(&tree_cl); + lodepng_free(frequencies_ll); + lodepng_free(frequencies_d); + lodepng_free(frequencies_cl); + lodepng_free(bitlen_lld); + lodepng_free(bitlen_lld_e); + + return error; +} + +static unsigned deflateFixed(LodePNGBitWriter* writer, Hash* hash, + const unsigned char* data, + size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { + HuffmanTree tree_ll; /*tree for literal values and length codes*/ + HuffmanTree tree_d; /*tree for distance codes*/ + + unsigned BFINAL = final; + unsigned error = 0; + size_t i; + + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + + error = generateFixedLitLenTree(&tree_ll); + if(!error) error = generateFixedDistanceTree(&tree_d); + + if(!error) { + writeBits(writer, BFINAL, 1); + writeBits(writer, 1, 1); /*first bit of BTYPE*/ + writeBits(writer, 0, 1); /*second bit of BTYPE*/ + + if(settings->use_lz77) /*LZ77 encoded*/ { + uivector lz77_encoded; + uivector_init(&lz77_encoded); + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); + uivector_cleanup(&lz77_encoded); + } else /*no LZ77, but still will be Huffman compressed*/ { + for(i = datapos; i < dataend; ++i) { + writeBitsReversed(writer, tree_ll.codes[data[i]], tree_ll.lengths[data[i]]); + } + } + /*add END code*/ + if(!error) writeBitsReversed(writer,tree_ll.codes[256], tree_ll.lengths[256]); + } + + /*cleanup*/ + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + + return error; +} + +static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + unsigned error = 0; + size_t i, blocksize, numdeflateblocks; + Hash hash; + LodePNGBitWriter writer; + + LodePNGBitWriter_init(&writer, out); + + if(settings->btype > 2) return 61; + else if(settings->btype == 0) return deflateNoCompression(out, in, insize); + else if(settings->btype == 1) blocksize = insize; + else /*if(settings->btype == 2)*/ { + /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ + blocksize = insize / 8u + 8; + if(blocksize < 65536) blocksize = 65536; + if(blocksize > 262144) blocksize = 262144; + } + + numdeflateblocks = (insize + blocksize - 1) / blocksize; + if(numdeflateblocks == 0) numdeflateblocks = 1; + + error = hash_init(&hash, settings->windowsize); + + if(!error) { + for(i = 0; i != numdeflateblocks && !error; ++i) { + unsigned final = (i == numdeflateblocks - 1); + size_t start = i * blocksize; + size_t end = start + blocksize; + if(end > insize) end = insize; + + if(settings->btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings, final); + else if(settings->btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings, final); + } + } + + hash_cleanup(&hash); + + return error; +} + +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + ucvector v = ucvector_init(*out, *outsize); + unsigned error = lodepng_deflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +static unsigned deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { + if(settings->custom_deflate) { + unsigned error = settings->custom_deflate(out, outsize, in, insize, settings); + /*the custom deflate is allowed to have its own error codes, however, we translate it to code 111*/ + return error ? 111 : 0; + } else { + return lodepng_deflate(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Adler32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) { + unsigned s1 = adler & 0xffffu; + unsigned s2 = (adler >> 16u) & 0xffffu; + + while(len != 0u) { + unsigned i; + /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/ + unsigned amount = len > 5552u ? 5552u : len; + len -= amount; + for(i = 0; i != amount; ++i) { + s1 += (*data++); + s2 += s1; + } + s1 %= 65521u; + s2 %= 65521u; + } + + return (s2 << 16u) | s1; +} + +/*Return the adler32 of the bytes data[0..len-1]*/ +static unsigned adler32(const unsigned char* data, unsigned len) { + return update_adler32(1u, data, len); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Zlib / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_DECODER + +static unsigned lodepng_zlib_decompressv(ucvector* out, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { + unsigned error = 0; + unsigned CM, CINFO, FDICT; + + if(insize < 2) return 53; /*error, size of zlib data too small*/ + /*read information from zlib header*/ + if((in[0] * 256 + in[1]) % 31 != 0) { + /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ + return 24; + } + + CM = in[0] & 15; + CINFO = (in[0] >> 4) & 15; + /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ + FDICT = (in[1] >> 5) & 1; + /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ + + if(CM != 8 || CINFO > 7) { + /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ + return 25; + } + if(FDICT != 0) { + /*error: the specification of PNG says about the zlib stream: + "The additional flags shall not specify a preset dictionary."*/ + return 26; + } + + error = inflatev(out, in + 2, insize - 2, settings); + if(error) return error; + + if(!settings->ignore_adler32) { + unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); + unsigned checksum = adler32(out->data, (unsigned)(out->size)); + if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ + } + + return 0; /*no error*/ +} + + +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGDecompressSettings* settings) { + ucvector v = ucvector_init(*out, *outsize); + unsigned error = lodepng_zlib_decompressv(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; +} + +/*expected_size is expected output size, to avoid intermediate allocations. Set to 0 if not known. */ +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, + const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { + unsigned error; + if(settings->custom_zlib) { + error = settings->custom_zlib(out, outsize, in, insize, settings); + if(error) { + /*the custom zlib is allowed to have its own error codes, however, we translate it to code 110*/ + error = 110; + /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/ + if(settings->max_output_size && *outsize > settings->max_output_size) error = 109; + } + } else { + ucvector v = ucvector_init(*out, *outsize); + if(expected_size) { + /*reserve the memory to avoid intermediate reallocations*/ + ucvector_resize(&v, *outsize + expected_size); + v.size = *outsize; + } + error = lodepng_zlib_decompressv(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + } + return error; +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER + +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + size_t i; + unsigned error; + unsigned char* deflatedata = 0; + size_t deflatesize = 0; + + error = deflate(&deflatedata, &deflatesize, in, insize, settings); + + *out = NULL; + *outsize = 0; + if(!error) { + *outsize = deflatesize + 6; + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!*out) error = 83; /*alloc fail*/ + } + + if(!error) { + unsigned ADLER32 = adler32(in, (unsigned)insize); + /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ + unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ + unsigned FLEVEL = 0; + unsigned FDICT = 0; + unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; + unsigned FCHECK = 31 - CMFFLG % 31; + CMFFLG += FCHECK; + + (*out)[0] = (unsigned char)(CMFFLG >> 8); + (*out)[1] = (unsigned char)(CMFFLG & 255); + for(i = 0; i != deflatesize; ++i) (*out)[i + 2] = deflatedata[i]; + lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32); + } + + lodepng_free(deflatedata); + return error; +} + +/* compress using the default or custom zlib function */ +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + if(settings->custom_zlib) { + unsigned error = settings->custom_zlib(out, outsize, in, insize, settings); + /*the custom zlib is allowed to have its own error codes, however, we translate it to code 111*/ + return error ? 111 : 0; + } else { + return lodepng_zlib_compress(out, outsize, in, insize, settings); + } +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#else /*no LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DECODER +static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, + const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + (void)expected_size; + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER +static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, + size_t insize, const LodePNGCompressSettings* settings) { + if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#endif /*LODEPNG_COMPILE_ZLIB*/ + +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/*this is a good tradeoff between speed and compression ratio*/ +#define DEFAULT_WINDOWSIZE 2048 + +void lodepng_compress_settings_init(LodePNGCompressSettings* settings) { + /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ + settings->btype = 2; + settings->use_lz77 = 1; + settings->windowsize = DEFAULT_WINDOWSIZE; + settings->minmatch = 3; + settings->nicematch = 128; + settings->lazymatching = 1; + + settings->custom_zlib = 0; + settings->custom_deflate = 0; + settings->custom_context = 0; +} + +const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; + + +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DECODER + +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) { + settings->ignore_adler32 = 0; + settings->ignore_nlen = 0; + settings->max_output_size = 0; + + settings->custom_zlib = 0; + settings->custom_inflate = 0; + settings->custom_context = 0; +} + +const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0, 0}; + +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // End of Zlib related code. Begin of PNG related code. // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_PNG + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / CRC32 / */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +#ifdef LODEPNG_COMPILE_CRC + +static const unsigned lodepng_crc32_table0[256] = { + 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u, + 0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u, + 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u, + 0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u, + 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu, + 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u, + 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu, + 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du, + 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u, + 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u, + 0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u, + 0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u, + 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu, + 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u, + 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu, + 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu, + 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u, + 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u, + 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u, + 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u, + 0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu, + 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u, + 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu, + 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du, + 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u, + 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u, + 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u, + 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u, + 0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu, + 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u, + 0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu, + 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du +}; + +static const unsigned lodepng_crc32_table1[256] = { + 0x00000000u, 0x191b3141u, 0x32366282u, 0x2b2d53c3u, 0x646cc504u, 0x7d77f445u, 0x565aa786u, 0x4f4196c7u, + 0xc8d98a08u, 0xd1c2bb49u, 0xfaefe88au, 0xe3f4d9cbu, 0xacb54f0cu, 0xb5ae7e4du, 0x9e832d8eu, 0x87981ccfu, + 0x4ac21251u, 0x53d92310u, 0x78f470d3u, 0x61ef4192u, 0x2eaed755u, 0x37b5e614u, 0x1c98b5d7u, 0x05838496u, + 0x821b9859u, 0x9b00a918u, 0xb02dfadbu, 0xa936cb9au, 0xe6775d5du, 0xff6c6c1cu, 0xd4413fdfu, 0xcd5a0e9eu, + 0x958424a2u, 0x8c9f15e3u, 0xa7b24620u, 0xbea97761u, 0xf1e8e1a6u, 0xe8f3d0e7u, 0xc3de8324u, 0xdac5b265u, + 0x5d5daeaau, 0x44469febu, 0x6f6bcc28u, 0x7670fd69u, 0x39316baeu, 0x202a5aefu, 0x0b07092cu, 0x121c386du, + 0xdf4636f3u, 0xc65d07b2u, 0xed705471u, 0xf46b6530u, 0xbb2af3f7u, 0xa231c2b6u, 0x891c9175u, 0x9007a034u, + 0x179fbcfbu, 0x0e848dbau, 0x25a9de79u, 0x3cb2ef38u, 0x73f379ffu, 0x6ae848beu, 0x41c51b7du, 0x58de2a3cu, + 0xf0794f05u, 0xe9627e44u, 0xc24f2d87u, 0xdb541cc6u, 0x94158a01u, 0x8d0ebb40u, 0xa623e883u, 0xbf38d9c2u, + 0x38a0c50du, 0x21bbf44cu, 0x0a96a78fu, 0x138d96ceu, 0x5ccc0009u, 0x45d73148u, 0x6efa628bu, 0x77e153cau, + 0xbabb5d54u, 0xa3a06c15u, 0x888d3fd6u, 0x91960e97u, 0xded79850u, 0xc7cca911u, 0xece1fad2u, 0xf5facb93u, + 0x7262d75cu, 0x6b79e61du, 0x4054b5deu, 0x594f849fu, 0x160e1258u, 0x0f152319u, 0x243870dau, 0x3d23419bu, + 0x65fd6ba7u, 0x7ce65ae6u, 0x57cb0925u, 0x4ed03864u, 0x0191aea3u, 0x188a9fe2u, 0x33a7cc21u, 0x2abcfd60u, + 0xad24e1afu, 0xb43fd0eeu, 0x9f12832du, 0x8609b26cu, 0xc94824abu, 0xd05315eau, 0xfb7e4629u, 0xe2657768u, + 0x2f3f79f6u, 0x362448b7u, 0x1d091b74u, 0x04122a35u, 0x4b53bcf2u, 0x52488db3u, 0x7965de70u, 0x607eef31u, + 0xe7e6f3feu, 0xfefdc2bfu, 0xd5d0917cu, 0xcccba03du, 0x838a36fau, 0x9a9107bbu, 0xb1bc5478u, 0xa8a76539u, + 0x3b83984bu, 0x2298a90au, 0x09b5fac9u, 0x10aecb88u, 0x5fef5d4fu, 0x46f46c0eu, 0x6dd93fcdu, 0x74c20e8cu, + 0xf35a1243u, 0xea412302u, 0xc16c70c1u, 0xd8774180u, 0x9736d747u, 0x8e2de606u, 0xa500b5c5u, 0xbc1b8484u, + 0x71418a1au, 0x685abb5bu, 0x4377e898u, 0x5a6cd9d9u, 0x152d4f1eu, 0x0c367e5fu, 0x271b2d9cu, 0x3e001cddu, + 0xb9980012u, 0xa0833153u, 0x8bae6290u, 0x92b553d1u, 0xddf4c516u, 0xc4eff457u, 0xefc2a794u, 0xf6d996d5u, + 0xae07bce9u, 0xb71c8da8u, 0x9c31de6bu, 0x852aef2au, 0xca6b79edu, 0xd37048acu, 0xf85d1b6fu, 0xe1462a2eu, + 0x66de36e1u, 0x7fc507a0u, 0x54e85463u, 0x4df36522u, 0x02b2f3e5u, 0x1ba9c2a4u, 0x30849167u, 0x299fa026u, + 0xe4c5aeb8u, 0xfdde9ff9u, 0xd6f3cc3au, 0xcfe8fd7bu, 0x80a96bbcu, 0x99b25afdu, 0xb29f093eu, 0xab84387fu, + 0x2c1c24b0u, 0x350715f1u, 0x1e2a4632u, 0x07317773u, 0x4870e1b4u, 0x516bd0f5u, 0x7a468336u, 0x635db277u, + 0xcbfad74eu, 0xd2e1e60fu, 0xf9ccb5ccu, 0xe0d7848du, 0xaf96124au, 0xb68d230bu, 0x9da070c8u, 0x84bb4189u, + 0x03235d46u, 0x1a386c07u, 0x31153fc4u, 0x280e0e85u, 0x674f9842u, 0x7e54a903u, 0x5579fac0u, 0x4c62cb81u, + 0x8138c51fu, 0x9823f45eu, 0xb30ea79du, 0xaa1596dcu, 0xe554001bu, 0xfc4f315au, 0xd7626299u, 0xce7953d8u, + 0x49e14f17u, 0x50fa7e56u, 0x7bd72d95u, 0x62cc1cd4u, 0x2d8d8a13u, 0x3496bb52u, 0x1fbbe891u, 0x06a0d9d0u, + 0x5e7ef3ecu, 0x4765c2adu, 0x6c48916eu, 0x7553a02fu, 0x3a1236e8u, 0x230907a9u, 0x0824546au, 0x113f652bu, + 0x96a779e4u, 0x8fbc48a5u, 0xa4911b66u, 0xbd8a2a27u, 0xf2cbbce0u, 0xebd08da1u, 0xc0fdde62u, 0xd9e6ef23u, + 0x14bce1bdu, 0x0da7d0fcu, 0x268a833fu, 0x3f91b27eu, 0x70d024b9u, 0x69cb15f8u, 0x42e6463bu, 0x5bfd777au, + 0xdc656bb5u, 0xc57e5af4u, 0xee530937u, 0xf7483876u, 0xb809aeb1u, 0xa1129ff0u, 0x8a3fcc33u, 0x9324fd72u +}; + +static const unsigned lodepng_crc32_table2[256] = { + 0x00000000u, 0x01c26a37u, 0x0384d46eu, 0x0246be59u, 0x0709a8dcu, 0x06cbc2ebu, 0x048d7cb2u, 0x054f1685u, + 0x0e1351b8u, 0x0fd13b8fu, 0x0d9785d6u, 0x0c55efe1u, 0x091af964u, 0x08d89353u, 0x0a9e2d0au, 0x0b5c473du, + 0x1c26a370u, 0x1de4c947u, 0x1fa2771eu, 0x1e601d29u, 0x1b2f0bacu, 0x1aed619bu, 0x18abdfc2u, 0x1969b5f5u, + 0x1235f2c8u, 0x13f798ffu, 0x11b126a6u, 0x10734c91u, 0x153c5a14u, 0x14fe3023u, 0x16b88e7au, 0x177ae44du, + 0x384d46e0u, 0x398f2cd7u, 0x3bc9928eu, 0x3a0bf8b9u, 0x3f44ee3cu, 0x3e86840bu, 0x3cc03a52u, 0x3d025065u, + 0x365e1758u, 0x379c7d6fu, 0x35dac336u, 0x3418a901u, 0x3157bf84u, 0x3095d5b3u, 0x32d36beau, 0x331101ddu, + 0x246be590u, 0x25a98fa7u, 0x27ef31feu, 0x262d5bc9u, 0x23624d4cu, 0x22a0277bu, 0x20e69922u, 0x2124f315u, + 0x2a78b428u, 0x2bbade1fu, 0x29fc6046u, 0x283e0a71u, 0x2d711cf4u, 0x2cb376c3u, 0x2ef5c89au, 0x2f37a2adu, + 0x709a8dc0u, 0x7158e7f7u, 0x731e59aeu, 0x72dc3399u, 0x7793251cu, 0x76514f2bu, 0x7417f172u, 0x75d59b45u, + 0x7e89dc78u, 0x7f4bb64fu, 0x7d0d0816u, 0x7ccf6221u, 0x798074a4u, 0x78421e93u, 0x7a04a0cau, 0x7bc6cafdu, + 0x6cbc2eb0u, 0x6d7e4487u, 0x6f38fadeu, 0x6efa90e9u, 0x6bb5866cu, 0x6a77ec5bu, 0x68315202u, 0x69f33835u, + 0x62af7f08u, 0x636d153fu, 0x612bab66u, 0x60e9c151u, 0x65a6d7d4u, 0x6464bde3u, 0x662203bau, 0x67e0698du, + 0x48d7cb20u, 0x4915a117u, 0x4b531f4eu, 0x4a917579u, 0x4fde63fcu, 0x4e1c09cbu, 0x4c5ab792u, 0x4d98dda5u, + 0x46c49a98u, 0x4706f0afu, 0x45404ef6u, 0x448224c1u, 0x41cd3244u, 0x400f5873u, 0x4249e62au, 0x438b8c1du, + 0x54f16850u, 0x55330267u, 0x5775bc3eu, 0x56b7d609u, 0x53f8c08cu, 0x523aaabbu, 0x507c14e2u, 0x51be7ed5u, + 0x5ae239e8u, 0x5b2053dfu, 0x5966ed86u, 0x58a487b1u, 0x5deb9134u, 0x5c29fb03u, 0x5e6f455au, 0x5fad2f6du, + 0xe1351b80u, 0xe0f771b7u, 0xe2b1cfeeu, 0xe373a5d9u, 0xe63cb35cu, 0xe7fed96bu, 0xe5b86732u, 0xe47a0d05u, + 0xef264a38u, 0xeee4200fu, 0xeca29e56u, 0xed60f461u, 0xe82fe2e4u, 0xe9ed88d3u, 0xebab368au, 0xea695cbdu, + 0xfd13b8f0u, 0xfcd1d2c7u, 0xfe976c9eu, 0xff5506a9u, 0xfa1a102cu, 0xfbd87a1bu, 0xf99ec442u, 0xf85cae75u, + 0xf300e948u, 0xf2c2837fu, 0xf0843d26u, 0xf1465711u, 0xf4094194u, 0xf5cb2ba3u, 0xf78d95fau, 0xf64fffcdu, + 0xd9785d60u, 0xd8ba3757u, 0xdafc890eu, 0xdb3ee339u, 0xde71f5bcu, 0xdfb39f8bu, 0xddf521d2u, 0xdc374be5u, + 0xd76b0cd8u, 0xd6a966efu, 0xd4efd8b6u, 0xd52db281u, 0xd062a404u, 0xd1a0ce33u, 0xd3e6706au, 0xd2241a5du, + 0xc55efe10u, 0xc49c9427u, 0xc6da2a7eu, 0xc7184049u, 0xc25756ccu, 0xc3953cfbu, 0xc1d382a2u, 0xc011e895u, + 0xcb4dafa8u, 0xca8fc59fu, 0xc8c97bc6u, 0xc90b11f1u, 0xcc440774u, 0xcd866d43u, 0xcfc0d31au, 0xce02b92du, + 0x91af9640u, 0x906dfc77u, 0x922b422eu, 0x93e92819u, 0x96a63e9cu, 0x976454abu, 0x9522eaf2u, 0x94e080c5u, + 0x9fbcc7f8u, 0x9e7eadcfu, 0x9c381396u, 0x9dfa79a1u, 0x98b56f24u, 0x99770513u, 0x9b31bb4au, 0x9af3d17du, + 0x8d893530u, 0x8c4b5f07u, 0x8e0de15eu, 0x8fcf8b69u, 0x8a809decu, 0x8b42f7dbu, 0x89044982u, 0x88c623b5u, + 0x839a6488u, 0x82580ebfu, 0x801eb0e6u, 0x81dcdad1u, 0x8493cc54u, 0x8551a663u, 0x8717183au, 0x86d5720du, + 0xa9e2d0a0u, 0xa820ba97u, 0xaa6604ceu, 0xaba46ef9u, 0xaeeb787cu, 0xaf29124bu, 0xad6fac12u, 0xacadc625u, + 0xa7f18118u, 0xa633eb2fu, 0xa4755576u, 0xa5b73f41u, 0xa0f829c4u, 0xa13a43f3u, 0xa37cfdaau, 0xa2be979du, + 0xb5c473d0u, 0xb40619e7u, 0xb640a7beu, 0xb782cd89u, 0xb2cddb0cu, 0xb30fb13bu, 0xb1490f62u, 0xb08b6555u, + 0xbbd72268u, 0xba15485fu, 0xb853f606u, 0xb9919c31u, 0xbcde8ab4u, 0xbd1ce083u, 0xbf5a5edau, 0xbe9834edu +}; + +static const unsigned lodepng_crc32_table3[256] = { + 0x00000000u, 0xb8bc6765u, 0xaa09c88bu, 0x12b5afeeu, 0x8f629757u, 0x37def032u, 0x256b5fdcu, 0x9dd738b9u, + 0xc5b428efu, 0x7d084f8au, 0x6fbde064u, 0xd7018701u, 0x4ad6bfb8u, 0xf26ad8ddu, 0xe0df7733u, 0x58631056u, + 0x5019579fu, 0xe8a530fau, 0xfa109f14u, 0x42acf871u, 0xdf7bc0c8u, 0x67c7a7adu, 0x75720843u, 0xcdce6f26u, + 0x95ad7f70u, 0x2d111815u, 0x3fa4b7fbu, 0x8718d09eu, 0x1acfe827u, 0xa2738f42u, 0xb0c620acu, 0x087a47c9u, + 0xa032af3eu, 0x188ec85bu, 0x0a3b67b5u, 0xb28700d0u, 0x2f503869u, 0x97ec5f0cu, 0x8559f0e2u, 0x3de59787u, + 0x658687d1u, 0xdd3ae0b4u, 0xcf8f4f5au, 0x7733283fu, 0xeae41086u, 0x525877e3u, 0x40edd80du, 0xf851bf68u, + 0xf02bf8a1u, 0x48979fc4u, 0x5a22302au, 0xe29e574fu, 0x7f496ff6u, 0xc7f50893u, 0xd540a77du, 0x6dfcc018u, + 0x359fd04eu, 0x8d23b72bu, 0x9f9618c5u, 0x272a7fa0u, 0xbafd4719u, 0x0241207cu, 0x10f48f92u, 0xa848e8f7u, + 0x9b14583du, 0x23a83f58u, 0x311d90b6u, 0x89a1f7d3u, 0x1476cf6au, 0xaccaa80fu, 0xbe7f07e1u, 0x06c36084u, + 0x5ea070d2u, 0xe61c17b7u, 0xf4a9b859u, 0x4c15df3cu, 0xd1c2e785u, 0x697e80e0u, 0x7bcb2f0eu, 0xc377486bu, + 0xcb0d0fa2u, 0x73b168c7u, 0x6104c729u, 0xd9b8a04cu, 0x446f98f5u, 0xfcd3ff90u, 0xee66507eu, 0x56da371bu, + 0x0eb9274du, 0xb6054028u, 0xa4b0efc6u, 0x1c0c88a3u, 0x81dbb01au, 0x3967d77fu, 0x2bd27891u, 0x936e1ff4u, + 0x3b26f703u, 0x839a9066u, 0x912f3f88u, 0x299358edu, 0xb4446054u, 0x0cf80731u, 0x1e4da8dfu, 0xa6f1cfbau, + 0xfe92dfecu, 0x462eb889u, 0x549b1767u, 0xec277002u, 0x71f048bbu, 0xc94c2fdeu, 0xdbf98030u, 0x6345e755u, + 0x6b3fa09cu, 0xd383c7f9u, 0xc1366817u, 0x798a0f72u, 0xe45d37cbu, 0x5ce150aeu, 0x4e54ff40u, 0xf6e89825u, + 0xae8b8873u, 0x1637ef16u, 0x048240f8u, 0xbc3e279du, 0x21e91f24u, 0x99557841u, 0x8be0d7afu, 0x335cb0cau, + 0xed59b63bu, 0x55e5d15eu, 0x47507eb0u, 0xffec19d5u, 0x623b216cu, 0xda874609u, 0xc832e9e7u, 0x708e8e82u, + 0x28ed9ed4u, 0x9051f9b1u, 0x82e4565fu, 0x3a58313au, 0xa78f0983u, 0x1f336ee6u, 0x0d86c108u, 0xb53aa66du, + 0xbd40e1a4u, 0x05fc86c1u, 0x1749292fu, 0xaff54e4au, 0x322276f3u, 0x8a9e1196u, 0x982bbe78u, 0x2097d91du, + 0x78f4c94bu, 0xc048ae2eu, 0xd2fd01c0u, 0x6a4166a5u, 0xf7965e1cu, 0x4f2a3979u, 0x5d9f9697u, 0xe523f1f2u, + 0x4d6b1905u, 0xf5d77e60u, 0xe762d18eu, 0x5fdeb6ebu, 0xc2098e52u, 0x7ab5e937u, 0x680046d9u, 0xd0bc21bcu, + 0x88df31eau, 0x3063568fu, 0x22d6f961u, 0x9a6a9e04u, 0x07bda6bdu, 0xbf01c1d8u, 0xadb46e36u, 0x15080953u, + 0x1d724e9au, 0xa5ce29ffu, 0xb77b8611u, 0x0fc7e174u, 0x9210d9cdu, 0x2aacbea8u, 0x38191146u, 0x80a57623u, + 0xd8c66675u, 0x607a0110u, 0x72cfaefeu, 0xca73c99bu, 0x57a4f122u, 0xef189647u, 0xfdad39a9u, 0x45115eccu, + 0x764dee06u, 0xcef18963u, 0xdc44268du, 0x64f841e8u, 0xf92f7951u, 0x41931e34u, 0x5326b1dau, 0xeb9ad6bfu, + 0xb3f9c6e9u, 0x0b45a18cu, 0x19f00e62u, 0xa14c6907u, 0x3c9b51beu, 0x842736dbu, 0x96929935u, 0x2e2efe50u, + 0x2654b999u, 0x9ee8defcu, 0x8c5d7112u, 0x34e11677u, 0xa9362eceu, 0x118a49abu, 0x033fe645u, 0xbb838120u, + 0xe3e09176u, 0x5b5cf613u, 0x49e959fdu, 0xf1553e98u, 0x6c820621u, 0xd43e6144u, 0xc68bceaau, 0x7e37a9cfu, + 0xd67f4138u, 0x6ec3265du, 0x7c7689b3u, 0xc4caeed6u, 0x591dd66fu, 0xe1a1b10au, 0xf3141ee4u, 0x4ba87981u, + 0x13cb69d7u, 0xab770eb2u, 0xb9c2a15cu, 0x017ec639u, 0x9ca9fe80u, 0x241599e5u, 0x36a0360bu, 0x8e1c516eu, + 0x866616a7u, 0x3eda71c2u, 0x2c6fde2cu, 0x94d3b949u, 0x090481f0u, 0xb1b8e695u, 0xa30d497bu, 0x1bb12e1eu, + 0x43d23e48u, 0xfb6e592du, 0xe9dbf6c3u, 0x516791a6u, 0xccb0a91fu, 0x740cce7au, 0x66b96194u, 0xde0506f1u +}; + +static const unsigned lodepng_crc32_table4[256] = { + 0x00000000u, 0x3d6029b0u, 0x7ac05360u, 0x47a07ad0u, 0xf580a6c0u, 0xc8e08f70u, 0x8f40f5a0u, 0xb220dc10u, + 0x30704bc1u, 0x0d106271u, 0x4ab018a1u, 0x77d03111u, 0xc5f0ed01u, 0xf890c4b1u, 0xbf30be61u, 0x825097d1u, + 0x60e09782u, 0x5d80be32u, 0x1a20c4e2u, 0x2740ed52u, 0x95603142u, 0xa80018f2u, 0xefa06222u, 0xd2c04b92u, + 0x5090dc43u, 0x6df0f5f3u, 0x2a508f23u, 0x1730a693u, 0xa5107a83u, 0x98705333u, 0xdfd029e3u, 0xe2b00053u, + 0xc1c12f04u, 0xfca106b4u, 0xbb017c64u, 0x866155d4u, 0x344189c4u, 0x0921a074u, 0x4e81daa4u, 0x73e1f314u, + 0xf1b164c5u, 0xccd14d75u, 0x8b7137a5u, 0xb6111e15u, 0x0431c205u, 0x3951ebb5u, 0x7ef19165u, 0x4391b8d5u, + 0xa121b886u, 0x9c419136u, 0xdbe1ebe6u, 0xe681c256u, 0x54a11e46u, 0x69c137f6u, 0x2e614d26u, 0x13016496u, + 0x9151f347u, 0xac31daf7u, 0xeb91a027u, 0xd6f18997u, 0x64d15587u, 0x59b17c37u, 0x1e1106e7u, 0x23712f57u, + 0x58f35849u, 0x659371f9u, 0x22330b29u, 0x1f532299u, 0xad73fe89u, 0x9013d739u, 0xd7b3ade9u, 0xead38459u, + 0x68831388u, 0x55e33a38u, 0x124340e8u, 0x2f236958u, 0x9d03b548u, 0xa0639cf8u, 0xe7c3e628u, 0xdaa3cf98u, + 0x3813cfcbu, 0x0573e67bu, 0x42d39cabu, 0x7fb3b51bu, 0xcd93690bu, 0xf0f340bbu, 0xb7533a6bu, 0x8a3313dbu, + 0x0863840au, 0x3503adbau, 0x72a3d76au, 0x4fc3fedau, 0xfde322cau, 0xc0830b7au, 0x872371aau, 0xba43581au, + 0x9932774du, 0xa4525efdu, 0xe3f2242du, 0xde920d9du, 0x6cb2d18du, 0x51d2f83du, 0x167282edu, 0x2b12ab5du, + 0xa9423c8cu, 0x9422153cu, 0xd3826fecu, 0xeee2465cu, 0x5cc29a4cu, 0x61a2b3fcu, 0x2602c92cu, 0x1b62e09cu, + 0xf9d2e0cfu, 0xc4b2c97fu, 0x8312b3afu, 0xbe729a1fu, 0x0c52460fu, 0x31326fbfu, 0x7692156fu, 0x4bf23cdfu, + 0xc9a2ab0eu, 0xf4c282beu, 0xb362f86eu, 0x8e02d1deu, 0x3c220dceu, 0x0142247eu, 0x46e25eaeu, 0x7b82771eu, + 0xb1e6b092u, 0x8c869922u, 0xcb26e3f2u, 0xf646ca42u, 0x44661652u, 0x79063fe2u, 0x3ea64532u, 0x03c66c82u, + 0x8196fb53u, 0xbcf6d2e3u, 0xfb56a833u, 0xc6368183u, 0x74165d93u, 0x49767423u, 0x0ed60ef3u, 0x33b62743u, + 0xd1062710u, 0xec660ea0u, 0xabc67470u, 0x96a65dc0u, 0x248681d0u, 0x19e6a860u, 0x5e46d2b0u, 0x6326fb00u, + 0xe1766cd1u, 0xdc164561u, 0x9bb63fb1u, 0xa6d61601u, 0x14f6ca11u, 0x2996e3a1u, 0x6e369971u, 0x5356b0c1u, + 0x70279f96u, 0x4d47b626u, 0x0ae7ccf6u, 0x3787e546u, 0x85a73956u, 0xb8c710e6u, 0xff676a36u, 0xc2074386u, + 0x4057d457u, 0x7d37fde7u, 0x3a978737u, 0x07f7ae87u, 0xb5d77297u, 0x88b75b27u, 0xcf1721f7u, 0xf2770847u, + 0x10c70814u, 0x2da721a4u, 0x6a075b74u, 0x576772c4u, 0xe547aed4u, 0xd8278764u, 0x9f87fdb4u, 0xa2e7d404u, + 0x20b743d5u, 0x1dd76a65u, 0x5a7710b5u, 0x67173905u, 0xd537e515u, 0xe857cca5u, 0xaff7b675u, 0x92979fc5u, + 0xe915e8dbu, 0xd475c16bu, 0x93d5bbbbu, 0xaeb5920bu, 0x1c954e1bu, 0x21f567abu, 0x66551d7bu, 0x5b3534cbu, + 0xd965a31au, 0xe4058aaau, 0xa3a5f07au, 0x9ec5d9cau, 0x2ce505dau, 0x11852c6au, 0x562556bau, 0x6b457f0au, + 0x89f57f59u, 0xb49556e9u, 0xf3352c39u, 0xce550589u, 0x7c75d999u, 0x4115f029u, 0x06b58af9u, 0x3bd5a349u, + 0xb9853498u, 0x84e51d28u, 0xc34567f8u, 0xfe254e48u, 0x4c059258u, 0x7165bbe8u, 0x36c5c138u, 0x0ba5e888u, + 0x28d4c7dfu, 0x15b4ee6fu, 0x521494bfu, 0x6f74bd0fu, 0xdd54611fu, 0xe03448afu, 0xa794327fu, 0x9af41bcfu, + 0x18a48c1eu, 0x25c4a5aeu, 0x6264df7eu, 0x5f04f6ceu, 0xed242adeu, 0xd044036eu, 0x97e479beu, 0xaa84500eu, + 0x4834505du, 0x755479edu, 0x32f4033du, 0x0f942a8du, 0xbdb4f69du, 0x80d4df2du, 0xc774a5fdu, 0xfa148c4du, + 0x78441b9cu, 0x4524322cu, 0x028448fcu, 0x3fe4614cu, 0x8dc4bd5cu, 0xb0a494ecu, 0xf704ee3cu, 0xca64c78cu +}; + +static const unsigned lodepng_crc32_table5[256] = { + 0x00000000u, 0xcb5cd3a5u, 0x4dc8a10bu, 0x869472aeu, 0x9b914216u, 0x50cd91b3u, 0xd659e31du, 0x1d0530b8u, + 0xec53826du, 0x270f51c8u, 0xa19b2366u, 0x6ac7f0c3u, 0x77c2c07bu, 0xbc9e13deu, 0x3a0a6170u, 0xf156b2d5u, + 0x03d6029bu, 0xc88ad13eu, 0x4e1ea390u, 0x85427035u, 0x9847408du, 0x531b9328u, 0xd58fe186u, 0x1ed33223u, + 0xef8580f6u, 0x24d95353u, 0xa24d21fdu, 0x6911f258u, 0x7414c2e0u, 0xbf481145u, 0x39dc63ebu, 0xf280b04eu, + 0x07ac0536u, 0xccf0d693u, 0x4a64a43du, 0x81387798u, 0x9c3d4720u, 0x57619485u, 0xd1f5e62bu, 0x1aa9358eu, + 0xebff875bu, 0x20a354feu, 0xa6372650u, 0x6d6bf5f5u, 0x706ec54du, 0xbb3216e8u, 0x3da66446u, 0xf6fab7e3u, + 0x047a07adu, 0xcf26d408u, 0x49b2a6a6u, 0x82ee7503u, 0x9feb45bbu, 0x54b7961eu, 0xd223e4b0u, 0x197f3715u, + 0xe82985c0u, 0x23755665u, 0xa5e124cbu, 0x6ebdf76eu, 0x73b8c7d6u, 0xb8e41473u, 0x3e7066ddu, 0xf52cb578u, + 0x0f580a6cu, 0xc404d9c9u, 0x4290ab67u, 0x89cc78c2u, 0x94c9487au, 0x5f959bdfu, 0xd901e971u, 0x125d3ad4u, + 0xe30b8801u, 0x28575ba4u, 0xaec3290au, 0x659ffaafu, 0x789aca17u, 0xb3c619b2u, 0x35526b1cu, 0xfe0eb8b9u, + 0x0c8e08f7u, 0xc7d2db52u, 0x4146a9fcu, 0x8a1a7a59u, 0x971f4ae1u, 0x5c439944u, 0xdad7ebeau, 0x118b384fu, + 0xe0dd8a9au, 0x2b81593fu, 0xad152b91u, 0x6649f834u, 0x7b4cc88cu, 0xb0101b29u, 0x36846987u, 0xfdd8ba22u, + 0x08f40f5au, 0xc3a8dcffu, 0x453cae51u, 0x8e607df4u, 0x93654d4cu, 0x58399ee9u, 0xdeadec47u, 0x15f13fe2u, + 0xe4a78d37u, 0x2ffb5e92u, 0xa96f2c3cu, 0x6233ff99u, 0x7f36cf21u, 0xb46a1c84u, 0x32fe6e2au, 0xf9a2bd8fu, + 0x0b220dc1u, 0xc07ede64u, 0x46eaaccau, 0x8db67f6fu, 0x90b34fd7u, 0x5bef9c72u, 0xdd7beedcu, 0x16273d79u, + 0xe7718facu, 0x2c2d5c09u, 0xaab92ea7u, 0x61e5fd02u, 0x7ce0cdbau, 0xb7bc1e1fu, 0x31286cb1u, 0xfa74bf14u, + 0x1eb014d8u, 0xd5ecc77du, 0x5378b5d3u, 0x98246676u, 0x852156ceu, 0x4e7d856bu, 0xc8e9f7c5u, 0x03b52460u, + 0xf2e396b5u, 0x39bf4510u, 0xbf2b37beu, 0x7477e41bu, 0x6972d4a3u, 0xa22e0706u, 0x24ba75a8u, 0xefe6a60du, + 0x1d661643u, 0xd63ac5e6u, 0x50aeb748u, 0x9bf264edu, 0x86f75455u, 0x4dab87f0u, 0xcb3ff55eu, 0x006326fbu, + 0xf135942eu, 0x3a69478bu, 0xbcfd3525u, 0x77a1e680u, 0x6aa4d638u, 0xa1f8059du, 0x276c7733u, 0xec30a496u, + 0x191c11eeu, 0xd240c24bu, 0x54d4b0e5u, 0x9f886340u, 0x828d53f8u, 0x49d1805du, 0xcf45f2f3u, 0x04192156u, + 0xf54f9383u, 0x3e134026u, 0xb8873288u, 0x73dbe12du, 0x6eded195u, 0xa5820230u, 0x2316709eu, 0xe84aa33bu, + 0x1aca1375u, 0xd196c0d0u, 0x5702b27eu, 0x9c5e61dbu, 0x815b5163u, 0x4a0782c6u, 0xcc93f068u, 0x07cf23cdu, + 0xf6999118u, 0x3dc542bdu, 0xbb513013u, 0x700de3b6u, 0x6d08d30eu, 0xa65400abu, 0x20c07205u, 0xeb9ca1a0u, + 0x11e81eb4u, 0xdab4cd11u, 0x5c20bfbfu, 0x977c6c1au, 0x8a795ca2u, 0x41258f07u, 0xc7b1fda9u, 0x0ced2e0cu, + 0xfdbb9cd9u, 0x36e74f7cu, 0xb0733dd2u, 0x7b2fee77u, 0x662adecfu, 0xad760d6au, 0x2be27fc4u, 0xe0beac61u, + 0x123e1c2fu, 0xd962cf8au, 0x5ff6bd24u, 0x94aa6e81u, 0x89af5e39u, 0x42f38d9cu, 0xc467ff32u, 0x0f3b2c97u, + 0xfe6d9e42u, 0x35314de7u, 0xb3a53f49u, 0x78f9ececu, 0x65fcdc54u, 0xaea00ff1u, 0x28347d5fu, 0xe368aefau, + 0x16441b82u, 0xdd18c827u, 0x5b8cba89u, 0x90d0692cu, 0x8dd55994u, 0x46898a31u, 0xc01df89fu, 0x0b412b3au, + 0xfa1799efu, 0x314b4a4au, 0xb7df38e4u, 0x7c83eb41u, 0x6186dbf9u, 0xaada085cu, 0x2c4e7af2u, 0xe712a957u, + 0x15921919u, 0xdececabcu, 0x585ab812u, 0x93066bb7u, 0x8e035b0fu, 0x455f88aau, 0xc3cbfa04u, 0x089729a1u, + 0xf9c19b74u, 0x329d48d1u, 0xb4093a7fu, 0x7f55e9dau, 0x6250d962u, 0xa90c0ac7u, 0x2f987869u, 0xe4c4abccu +}; + +static const unsigned lodepng_crc32_table6[256] = { + 0x00000000u, 0xa6770bb4u, 0x979f1129u, 0x31e81a9du, 0xf44f2413u, 0x52382fa7u, 0x63d0353au, 0xc5a73e8eu, + 0x33ef4e67u, 0x959845d3u, 0xa4705f4eu, 0x020754fau, 0xc7a06a74u, 0x61d761c0u, 0x503f7b5du, 0xf64870e9u, + 0x67de9cceu, 0xc1a9977au, 0xf0418de7u, 0x56368653u, 0x9391b8ddu, 0x35e6b369u, 0x040ea9f4u, 0xa279a240u, + 0x5431d2a9u, 0xf246d91du, 0xc3aec380u, 0x65d9c834u, 0xa07ef6bau, 0x0609fd0eu, 0x37e1e793u, 0x9196ec27u, + 0xcfbd399cu, 0x69ca3228u, 0x582228b5u, 0xfe552301u, 0x3bf21d8fu, 0x9d85163bu, 0xac6d0ca6u, 0x0a1a0712u, + 0xfc5277fbu, 0x5a257c4fu, 0x6bcd66d2u, 0xcdba6d66u, 0x081d53e8u, 0xae6a585cu, 0x9f8242c1u, 0x39f54975u, + 0xa863a552u, 0x0e14aee6u, 0x3ffcb47bu, 0x998bbfcfu, 0x5c2c8141u, 0xfa5b8af5u, 0xcbb39068u, 0x6dc49bdcu, + 0x9b8ceb35u, 0x3dfbe081u, 0x0c13fa1cu, 0xaa64f1a8u, 0x6fc3cf26u, 0xc9b4c492u, 0xf85cde0fu, 0x5e2bd5bbu, + 0x440b7579u, 0xe27c7ecdu, 0xd3946450u, 0x75e36fe4u, 0xb044516au, 0x16335adeu, 0x27db4043u, 0x81ac4bf7u, + 0x77e43b1eu, 0xd19330aau, 0xe07b2a37u, 0x460c2183u, 0x83ab1f0du, 0x25dc14b9u, 0x14340e24u, 0xb2430590u, + 0x23d5e9b7u, 0x85a2e203u, 0xb44af89eu, 0x123df32au, 0xd79acda4u, 0x71edc610u, 0x4005dc8du, 0xe672d739u, + 0x103aa7d0u, 0xb64dac64u, 0x87a5b6f9u, 0x21d2bd4du, 0xe47583c3u, 0x42028877u, 0x73ea92eau, 0xd59d995eu, + 0x8bb64ce5u, 0x2dc14751u, 0x1c295dccu, 0xba5e5678u, 0x7ff968f6u, 0xd98e6342u, 0xe86679dfu, 0x4e11726bu, + 0xb8590282u, 0x1e2e0936u, 0x2fc613abu, 0x89b1181fu, 0x4c162691u, 0xea612d25u, 0xdb8937b8u, 0x7dfe3c0cu, + 0xec68d02bu, 0x4a1fdb9fu, 0x7bf7c102u, 0xdd80cab6u, 0x1827f438u, 0xbe50ff8cu, 0x8fb8e511u, 0x29cfeea5u, + 0xdf879e4cu, 0x79f095f8u, 0x48188f65u, 0xee6f84d1u, 0x2bc8ba5fu, 0x8dbfb1ebu, 0xbc57ab76u, 0x1a20a0c2u, + 0x8816eaf2u, 0x2e61e146u, 0x1f89fbdbu, 0xb9fef06fu, 0x7c59cee1u, 0xda2ec555u, 0xebc6dfc8u, 0x4db1d47cu, + 0xbbf9a495u, 0x1d8eaf21u, 0x2c66b5bcu, 0x8a11be08u, 0x4fb68086u, 0xe9c18b32u, 0xd82991afu, 0x7e5e9a1bu, + 0xefc8763cu, 0x49bf7d88u, 0x78576715u, 0xde206ca1u, 0x1b87522fu, 0xbdf0599bu, 0x8c184306u, 0x2a6f48b2u, + 0xdc27385bu, 0x7a5033efu, 0x4bb82972u, 0xedcf22c6u, 0x28681c48u, 0x8e1f17fcu, 0xbff70d61u, 0x198006d5u, + 0x47abd36eu, 0xe1dcd8dau, 0xd034c247u, 0x7643c9f3u, 0xb3e4f77du, 0x1593fcc9u, 0x247be654u, 0x820cede0u, + 0x74449d09u, 0xd23396bdu, 0xe3db8c20u, 0x45ac8794u, 0x800bb91au, 0x267cb2aeu, 0x1794a833u, 0xb1e3a387u, + 0x20754fa0u, 0x86024414u, 0xb7ea5e89u, 0x119d553du, 0xd43a6bb3u, 0x724d6007u, 0x43a57a9au, 0xe5d2712eu, + 0x139a01c7u, 0xb5ed0a73u, 0x840510eeu, 0x22721b5au, 0xe7d525d4u, 0x41a22e60u, 0x704a34fdu, 0xd63d3f49u, + 0xcc1d9f8bu, 0x6a6a943fu, 0x5b828ea2u, 0xfdf58516u, 0x3852bb98u, 0x9e25b02cu, 0xafcdaab1u, 0x09baa105u, + 0xfff2d1ecu, 0x5985da58u, 0x686dc0c5u, 0xce1acb71u, 0x0bbdf5ffu, 0xadcafe4bu, 0x9c22e4d6u, 0x3a55ef62u, + 0xabc30345u, 0x0db408f1u, 0x3c5c126cu, 0x9a2b19d8u, 0x5f8c2756u, 0xf9fb2ce2u, 0xc813367fu, 0x6e643dcbu, + 0x982c4d22u, 0x3e5b4696u, 0x0fb35c0bu, 0xa9c457bfu, 0x6c636931u, 0xca146285u, 0xfbfc7818u, 0x5d8b73acu, + 0x03a0a617u, 0xa5d7ada3u, 0x943fb73eu, 0x3248bc8au, 0xf7ef8204u, 0x519889b0u, 0x6070932du, 0xc6079899u, + 0x304fe870u, 0x9638e3c4u, 0xa7d0f959u, 0x01a7f2edu, 0xc400cc63u, 0x6277c7d7u, 0x539fdd4au, 0xf5e8d6feu, + 0x647e3ad9u, 0xc209316du, 0xf3e12bf0u, 0x55962044u, 0x90311ecau, 0x3646157eu, 0x07ae0fe3u, 0xa1d90457u, + 0x579174beu, 0xf1e67f0au, 0xc00e6597u, 0x66796e23u, 0xa3de50adu, 0x05a95b19u, 0x34414184u, 0x92364a30u +}; + +static const unsigned lodepng_crc32_table7[256] = { + 0x00000000u, 0xccaa009eu, 0x4225077du, 0x8e8f07e3u, 0x844a0efau, 0x48e00e64u, 0xc66f0987u, 0x0ac50919u, + 0xd3e51bb5u, 0x1f4f1b2bu, 0x91c01cc8u, 0x5d6a1c56u, 0x57af154fu, 0x9b0515d1u, 0x158a1232u, 0xd92012acu, + 0x7cbb312bu, 0xb01131b5u, 0x3e9e3656u, 0xf23436c8u, 0xf8f13fd1u, 0x345b3f4fu, 0xbad438acu, 0x767e3832u, + 0xaf5e2a9eu, 0x63f42a00u, 0xed7b2de3u, 0x21d12d7du, 0x2b142464u, 0xe7be24fau, 0x69312319u, 0xa59b2387u, + 0xf9766256u, 0x35dc62c8u, 0xbb53652bu, 0x77f965b5u, 0x7d3c6cacu, 0xb1966c32u, 0x3f196bd1u, 0xf3b36b4fu, + 0x2a9379e3u, 0xe639797du, 0x68b67e9eu, 0xa41c7e00u, 0xaed97719u, 0x62737787u, 0xecfc7064u, 0x205670fau, + 0x85cd537du, 0x496753e3u, 0xc7e85400u, 0x0b42549eu, 0x01875d87u, 0xcd2d5d19u, 0x43a25afau, 0x8f085a64u, + 0x562848c8u, 0x9a824856u, 0x140d4fb5u, 0xd8a74f2bu, 0xd2624632u, 0x1ec846acu, 0x9047414fu, 0x5ced41d1u, + 0x299dc2edu, 0xe537c273u, 0x6bb8c590u, 0xa712c50eu, 0xadd7cc17u, 0x617dcc89u, 0xeff2cb6au, 0x2358cbf4u, + 0xfa78d958u, 0x36d2d9c6u, 0xb85dde25u, 0x74f7debbu, 0x7e32d7a2u, 0xb298d73cu, 0x3c17d0dfu, 0xf0bdd041u, + 0x5526f3c6u, 0x998cf358u, 0x1703f4bbu, 0xdba9f425u, 0xd16cfd3cu, 0x1dc6fda2u, 0x9349fa41u, 0x5fe3fadfu, + 0x86c3e873u, 0x4a69e8edu, 0xc4e6ef0eu, 0x084cef90u, 0x0289e689u, 0xce23e617u, 0x40ace1f4u, 0x8c06e16au, + 0xd0eba0bbu, 0x1c41a025u, 0x92cea7c6u, 0x5e64a758u, 0x54a1ae41u, 0x980baedfu, 0x1684a93cu, 0xda2ea9a2u, + 0x030ebb0eu, 0xcfa4bb90u, 0x412bbc73u, 0x8d81bcedu, 0x8744b5f4u, 0x4beeb56au, 0xc561b289u, 0x09cbb217u, + 0xac509190u, 0x60fa910eu, 0xee7596edu, 0x22df9673u, 0x281a9f6au, 0xe4b09ff4u, 0x6a3f9817u, 0xa6959889u, + 0x7fb58a25u, 0xb31f8abbu, 0x3d908d58u, 0xf13a8dc6u, 0xfbff84dfu, 0x37558441u, 0xb9da83a2u, 0x7570833cu, + 0x533b85dau, 0x9f918544u, 0x111e82a7u, 0xddb48239u, 0xd7718b20u, 0x1bdb8bbeu, 0x95548c5du, 0x59fe8cc3u, + 0x80de9e6fu, 0x4c749ef1u, 0xc2fb9912u, 0x0e51998cu, 0x04949095u, 0xc83e900bu, 0x46b197e8u, 0x8a1b9776u, + 0x2f80b4f1u, 0xe32ab46fu, 0x6da5b38cu, 0xa10fb312u, 0xabcaba0bu, 0x6760ba95u, 0xe9efbd76u, 0x2545bde8u, + 0xfc65af44u, 0x30cfafdau, 0xbe40a839u, 0x72eaa8a7u, 0x782fa1beu, 0xb485a120u, 0x3a0aa6c3u, 0xf6a0a65du, + 0xaa4de78cu, 0x66e7e712u, 0xe868e0f1u, 0x24c2e06fu, 0x2e07e976u, 0xe2ade9e8u, 0x6c22ee0bu, 0xa088ee95u, + 0x79a8fc39u, 0xb502fca7u, 0x3b8dfb44u, 0xf727fbdau, 0xfde2f2c3u, 0x3148f25du, 0xbfc7f5beu, 0x736df520u, + 0xd6f6d6a7u, 0x1a5cd639u, 0x94d3d1dau, 0x5879d144u, 0x52bcd85du, 0x9e16d8c3u, 0x1099df20u, 0xdc33dfbeu, + 0x0513cd12u, 0xc9b9cd8cu, 0x4736ca6fu, 0x8b9ccaf1u, 0x8159c3e8u, 0x4df3c376u, 0xc37cc495u, 0x0fd6c40bu, + 0x7aa64737u, 0xb60c47a9u, 0x3883404au, 0xf42940d4u, 0xfeec49cdu, 0x32464953u, 0xbcc94eb0u, 0x70634e2eu, + 0xa9435c82u, 0x65e95c1cu, 0xeb665bffu, 0x27cc5b61u, 0x2d095278u, 0xe1a352e6u, 0x6f2c5505u, 0xa386559bu, + 0x061d761cu, 0xcab77682u, 0x44387161u, 0x889271ffu, 0x825778e6u, 0x4efd7878u, 0xc0727f9bu, 0x0cd87f05u, + 0xd5f86da9u, 0x19526d37u, 0x97dd6ad4u, 0x5b776a4au, 0x51b26353u, 0x9d1863cdu, 0x1397642eu, 0xdf3d64b0u, + 0x83d02561u, 0x4f7a25ffu, 0xc1f5221cu, 0x0d5f2282u, 0x079a2b9bu, 0xcb302b05u, 0x45bf2ce6u, 0x89152c78u, + 0x50353ed4u, 0x9c9f3e4au, 0x121039a9u, 0xdeba3937u, 0xd47f302eu, 0x18d530b0u, 0x965a3753u, 0x5af037cdu, + 0xff6b144au, 0x33c114d4u, 0xbd4e1337u, 0x71e413a9u, 0x7b211ab0u, 0xb78b1a2eu, 0x39041dcdu, 0xf5ae1d53u, + 0x2c8e0fffu, 0xe0240f61u, 0x6eab0882u, 0xa201081cu, 0xa8c40105u, 0x646e019bu, 0xeae10678u, 0x264b06e6u +}; + +/* Computes the cyclic redundancy check as used by PNG chunks*/ +unsigned lodepng_crc32(const unsigned char* data, size_t length) { + /*Using the Slicing by Eight algorithm*/ + unsigned r = 0xffffffffu; + while(length >= 8) { + r = lodepng_crc32_table7[(data[0] ^ (r & 0xffu))] ^ + lodepng_crc32_table6[(data[1] ^ ((r >> 8) & 0xffu))] ^ + lodepng_crc32_table5[(data[2] ^ ((r >> 16) & 0xffu))] ^ + lodepng_crc32_table4[(data[3] ^ ((r >> 24) & 0xffu))] ^ + lodepng_crc32_table3[data[4]] ^ + lodepng_crc32_table2[data[5]] ^ + lodepng_crc32_table1[data[6]] ^ + lodepng_crc32_table0[data[7]]; + data += 8; + length -= 8; + } + while(length--) { + r = lodepng_crc32_table0[(r ^ *data++) & 0xffu] ^ (r >> 8); + } + return r ^ 0xffffffffu; +} +#else /* LODEPNG_COMPILE_CRC */ +/*in this case, the function is only declared here, and must be defined externally +so that it will be linked in. + +Example implementation that uses a much smaller lookup table for memory constrained cases: + +unsigned lodepng_crc32(const unsigned char* data, size_t length) { + unsigned r = 0xffffffffu; + static const unsigned table[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + while(length--) { + r = table[(r ^ *data) & 0xf] ^ (r >> 4); + r = table[(r ^ (*data >> 4)) & 0xf] ^ (r >> 4); + data++; + } + return r ^ 0xffffffffu; +} +*/ +unsigned lodepng_crc32(const unsigned char* data, size_t length); +#endif /* LODEPNG_COMPILE_CRC */ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Reading and writing PNG color channel bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first, +so LodePNGBitWriter and LodePNGBitReader can't be used for those. */ + +static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { + unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); + ++(*bitpointer); + return result; +} + +/* TODO: make this faster */ +static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { + unsigned result = 0; + size_t i; + for(i = 0 ; i < nbits; ++i) { + result <<= 1u; + result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); + } + return result; +} + +static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { + /*the current bit in bitstream may be 0 or 1 for this to work*/ + if(bit == 0) bitstream[(*bitpointer) >> 3u] &= (unsigned char)(~(1u << (7u - ((*bitpointer) & 7u)))); + else bitstream[(*bitpointer) >> 3u] |= (1u << (7u - ((*bitpointer) & 7u))); + ++(*bitpointer); +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG chunks / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +unsigned lodepng_chunk_length(const unsigned char* chunk) { + return lodepng_read32bitInt(chunk); +} + +void lodepng_chunk_type(char type[5], const unsigned char* chunk) { + unsigned i; + for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; + type[4] = 0; /*null termination char*/ +} + +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) { + if(lodepng_strlen(type) != 4) return 0; + return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); +} + +/* chunk type name must exist only out of alphabetic characters a-z or A-Z */ +static unsigned char lodepng_chunk_type_name_valid(const unsigned char* chunk) { + unsigned i; + for(i = 0; i != 4; ++i) { + char c = (char)chunk[4 + i]; + if(!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) { + return 0; /* not valid */ + } + } + return 1; /* valid */ +} + +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) { + return((chunk[4] & 32) != 0); +} + +unsigned char lodepng_chunk_private(const unsigned char* chunk) { + return((chunk[5] & 32) != 0); +} + +/* this is an error if it is reserved: the third character must be uppercase in the PNG standard, +lowercasing this character is reserved for possible future extension by the spec*/ +static unsigned char lodepng_chunk_reserved(const unsigned char* chunk) { + return((chunk[6] & 32) != 0); +} + +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) { + return((chunk[7] & 32) != 0); +} + +unsigned char* lodepng_chunk_data(unsigned char* chunk) { + return &chunk[8]; +} + +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) { + return &chunk[8]; +} + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk) { + unsigned length = lodepng_chunk_length(chunk); + unsigned crc = lodepng_read32bitInt(&chunk[length + 8]); + /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ + unsigned checksum = lodepng_crc32(&chunk[4], length + 4); + if(crc != checksum) return 1; + else return 0; +} + +void lodepng_chunk_generate_crc(unsigned char* chunk) { + unsigned length = lodepng_chunk_length(chunk); + unsigned crc = lodepng_crc32(&chunk[4], length + 4); + lodepng_set32bitInt(chunk + 8 + length, crc); +} + +unsigned char* lodepng_chunk_next(unsigned char* chunk, unsigned char* end) { + size_t available_size = (size_t)(end - chunk); + if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/ + if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 + && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { + /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ + return chunk + 8; + } else { + size_t total_chunk_length; + if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; + if(total_chunk_length > available_size) return end; /*outside of range*/ + return chunk + total_chunk_length; + } +} + +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end) { + size_t available_size = (size_t)(end - chunk); + if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/ + if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 + && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { + /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ + return chunk + 8; + } else { + size_t total_chunk_length; + if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; + if(total_chunk_length > available_size) return end; /*outside of range*/ + return chunk + total_chunk_length; + } +} + +unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, const char type[5]) { + for(;;) { + if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */ + if(lodepng_chunk_type_equals(chunk, type)) return chunk; + chunk = lodepng_chunk_next(chunk, end); + } +} + +const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]) { + for(;;) { + if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */ + if(lodepng_chunk_type_equals(chunk, type)) return chunk; + chunk = lodepng_chunk_next_const(chunk, end); + } +} + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk) { + unsigned i; + size_t total_chunk_length, new_length; + unsigned char *chunk_start, *new_buffer; + + if(!lodepng_chunk_type_name_valid(chunk)) { + return 121; /* invalid chunk type name */ + } + if(lodepng_chunk_reserved(chunk)) { + return 122; /* invalid third lowercase character */ + } + + if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return 77; + if(lodepng_addofl(*outsize, total_chunk_length, &new_length)) return 77; + + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if(!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outsize) = new_length; + chunk_start = &(*out)[new_length - total_chunk_length]; + + for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; + + return 0; +} + +/*Sets length and name and allocates the space for data and crc but does not +set data or crc yet. Returns the start of the chunk in chunk. The start of +the data is at chunk + 8. To finalize chunk, add the data, then use +lodepng_chunk_generate_crc */ +static unsigned lodepng_chunk_init(unsigned char** chunk, + ucvector* out, + size_t length, const char* type) { + size_t new_length = out->size; + if(lodepng_addofl(new_length, length, &new_length)) return 77; + if(lodepng_addofl(new_length, 12, &new_length)) return 77; + if(!ucvector_resize(out, new_length)) return 83; /*alloc fail*/ + *chunk = out->data + new_length - length - 12u; + + /*1: length*/ + lodepng_set32bitInt(*chunk, (unsigned)length); + + /*2: chunk name (4 letters)*/ + lodepng_memcpy(*chunk + 4, type, 4); + + return 0; +} + +/* like lodepng_chunk_create but with custom allocsize */ +static unsigned lodepng_chunk_createv(ucvector* out, + size_t length, const char* type, const unsigned char* data) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, length, type)); + + /*3: the data*/ + lodepng_memcpy(chunk + 8, data, length); + + /*4: CRC (of the chunkname characters and the data)*/ + lodepng_chunk_generate_crc(chunk); + + return 0; +} + +unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, + size_t length, const char* type, const unsigned char* data) { + ucvector v = ucvector_init(*out, *outsize); + unsigned error = lodepng_chunk_createv(&v, length, type, data); + *out = v.data; + *outsize = v.size; + return error; +} + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / Color types, channels, bits / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*checks if the colortype is valid and the bitdepth bd is allowed for this colortype. +Return value is a LodePNG error code.*/ +static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) { + switch(colortype) { + case LCT_GREY: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; + case LCT_RGB: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_PALETTE: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; + case LCT_GREY_ALPHA: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_RGBA: if(!( bd == 8 || bd == 16)) return 37; break; + case LCT_MAX_OCTET_VALUE: return 31; /* invalid color type */ + default: return 31; /* invalid color type */ + } + return 0; /*allowed color type / bits combination*/ +} + +static unsigned getNumColorChannels(LodePNGColorType colortype) { + switch(colortype) { + case LCT_GREY: return 1; + case LCT_RGB: return 3; + case LCT_PALETTE: return 1; + case LCT_GREY_ALPHA: return 2; + case LCT_RGBA: return 4; + case LCT_MAX_OCTET_VALUE: return 0; /* invalid color type */ + default: return 0; /*invalid color type*/ + } +} + +static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) { + /*bits per pixel is amount of channels * bits per channel*/ + return getNumColorChannels(colortype) * bitdepth; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +void lodepng_color_mode_init(LodePNGColorMode* info) { + info->key_defined = 0; + info->key_r = info->key_g = info->key_b = 0; + info->colortype = LCT_RGBA; + info->bitdepth = 8; + info->palette = 0; + info->palettesize = 0; +} + +/*allocates palette memory if needed, and initializes all colors to black*/ +static void lodepng_color_mode_alloc_palette(LodePNGColorMode* info) { + size_t i; + /*if the palette is already allocated, it will have size 1024 so no reallocation needed in that case*/ + /*the palette must have room for up to 256 colors with 4 bytes each.*/ + if(!info->palette) info->palette = (unsigned char*)lodepng_malloc(1024); + if(!info->palette) return; /*alloc fail*/ + for(i = 0; i != 256; ++i) { + /*Initialize all unused colors with black, the value used for invalid palette indices. + This is an error according to the PNG spec, but common PNG decoders make it black instead. + That makes color conversion slightly faster due to no error handling needed.*/ + info->palette[i * 4 + 0] = 0; + info->palette[i * 4 + 1] = 0; + info->palette[i * 4 + 2] = 0; + info->palette[i * 4 + 3] = 255; + } +} + +void lodepng_color_mode_cleanup(LodePNGColorMode* info) { + lodepng_palette_clear(info); +} + +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) { + lodepng_color_mode_cleanup(dest); + lodepng_memcpy(dest, source, sizeof(LodePNGColorMode)); + if(source->palette) { + dest->palette = (unsigned char*)lodepng_malloc(1024); + if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ + lodepng_memcpy(dest->palette, source->palette, source->palettesize * 4); + } + return 0; +} + +LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth) { + LodePNGColorMode result; + lodepng_color_mode_init(&result); + result.colortype = colortype; + result.bitdepth = bitdepth; + return result; +} + +static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) { + size_t i; + if(a->colortype != b->colortype) return 0; + if(a->bitdepth != b->bitdepth) return 0; + if(a->key_defined != b->key_defined) return 0; + if(a->key_defined) { + if(a->key_r != b->key_r) return 0; + if(a->key_g != b->key_g) return 0; + if(a->key_b != b->key_b) return 0; + } + if(a->palettesize != b->palettesize) return 0; + for(i = 0; i != a->palettesize * 4; ++i) { + if(a->palette[i] != b->palette[i]) return 0; + } + return 1; +} + +void lodepng_palette_clear(LodePNGColorMode* info) { + if(info->palette) lodepng_free(info->palette); + info->palette = 0; + info->palettesize = 0; +} + +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if(!info->palette) /*allocate palette if empty*/ { + lodepng_color_mode_alloc_palette(info); + if(!info->palette) return 83; /*alloc fail*/ + } + if(info->palettesize >= 256) { + return 108; /*too many palette values*/ + } + info->palette[4 * info->palettesize + 0] = r; + info->palette[4 * info->palettesize + 1] = g; + info->palette[4 * info->palettesize + 2] = b; + info->palette[4 * info->palettesize + 3] = a; + ++info->palettesize; + return 0; +} + +/*calculate bits per pixel out of colortype and bitdepth*/ +unsigned lodepng_get_bpp(const LodePNGColorMode* info) { + return lodepng_get_bpp_lct(info->colortype, info->bitdepth); +} + +unsigned lodepng_get_channels(const LodePNGColorMode* info) { + return getNumColorChannels(info->colortype); +} + +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) { + return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; +} + +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) { + return (info->colortype & 4) != 0; /*4 or 6*/ +} + +unsigned lodepng_is_palette_type(const LodePNGColorMode* info) { + return info->colortype == LCT_PALETTE; +} + +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { + size_t i; + for(i = 0; i != info->palettesize; ++i) { + if(info->palette[i * 4 + 3] < 255) return 1; + } + return 0; +} + +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) { + return info->key_defined + || lodepng_is_alpha_type(info) + || lodepng_has_palette_alpha(info); +} + +static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { + size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); + size_t n = (size_t)w * (size_t)h; + return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u; +} + +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { + return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth); +} + + +#ifdef LODEPNG_COMPILE_PNG + +/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer, +and in addition has one extra byte per line: the filter byte. So this gives a larger +result than lodepng_get_raw_size. Set h to 1 to get the size of 1 row including filter byte. */ +static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, unsigned bpp) { + /* + 1 for the filter byte, and possibly plus padding bits per line. */ + /* Ignoring casts, the expression is equal to (w * bpp + 7) / 8 + 1, but avoids overflow of w * bpp */ + size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u; + return (size_t)h * line; +} + +#ifdef LODEPNG_COMPILE_DECODER +/*Safely checks whether size_t overflow can be caused due to amount of pixels. +This check is overcautious rather than precise. If this check indicates no overflow, +you can safely compute in a size_t (but not an unsigned): +-(size_t)w * (size_t)h * 8 +-amount of bytes in IDAT (including filter, padding and Adam7 bytes) +-amount of bytes in raw color model +Returns 1 if overflow possible, 0 if not. +*/ +static int lodepng_pixel_overflow(unsigned w, unsigned h, + const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor) { + size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor)); + size_t numpixels, total; + size_t line; /* bytes per line in worst case */ + + if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1; + if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */ + + /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */ + if(lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1; + if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1; + + if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */ + if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */ + + return 0; /* no overflow */ +} +#endif /*LODEPNG_COMPILE_DECODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static void LodePNGUnknownChunks_init(LodePNGInfo* info) { + unsigned i; + for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; + for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; +} + +static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { + unsigned i; + for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); +} + +static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) { + unsigned i; + + LodePNGUnknownChunks_cleanup(dest); + + for(i = 0; i != 3; ++i) { + size_t j; + dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; + dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); + if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ + for(j = 0; j < src->unknown_chunks_size[i]; ++j) { + dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; + } + } + + return 0; +} + +/******************************************************************************/ + +static void LodePNGText_init(LodePNGInfo* info) { + info->text_num = 0; + info->text_keys = NULL; + info->text_strings = NULL; +} + +static void LodePNGText_cleanup(LodePNGInfo* info) { + size_t i; + for(i = 0; i != info->text_num; ++i) { + string_cleanup(&info->text_keys[i]); + string_cleanup(&info->text_strings[i]); + } + lodepng_free(info->text_keys); + lodepng_free(info->text_strings); +} + +static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + size_t i = 0; + dest->text_keys = NULL; + dest->text_strings = NULL; + dest->text_num = 0; + for(i = 0; i != source->text_num; ++i) { + CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); + } + return 0; +} + +static unsigned lodepng_add_text_sized(LodePNGInfo* info, const char* key, const char* str, size_t size) { + char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); + + if(new_keys) info->text_keys = new_keys; + if(new_strings) info->text_strings = new_strings; + + if(!new_keys || !new_strings) return 83; /*alloc fail*/ + + ++info->text_num; + info->text_keys[info->text_num - 1] = alloc_string(key); + info->text_strings[info->text_num - 1] = alloc_string_sized(str, size); + if(!info->text_keys[info->text_num - 1] || !info->text_strings[info->text_num - 1]) return 83; /*alloc fail*/ + + return 0; +} + +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) { + return lodepng_add_text_sized(info, key, str, lodepng_strlen(str)); +} + +void lodepng_clear_text(LodePNGInfo* info) { + LodePNGText_cleanup(info); +} + +/******************************************************************************/ + +static void LodePNGIText_init(LodePNGInfo* info) { + info->itext_num = 0; + info->itext_keys = NULL; + info->itext_langtags = NULL; + info->itext_transkeys = NULL; + info->itext_strings = NULL; +} + +static void LodePNGIText_cleanup(LodePNGInfo* info) { + size_t i; + for(i = 0; i != info->itext_num; ++i) { + string_cleanup(&info->itext_keys[i]); + string_cleanup(&info->itext_langtags[i]); + string_cleanup(&info->itext_transkeys[i]); + string_cleanup(&info->itext_strings[i]); + } + lodepng_free(info->itext_keys); + lodepng_free(info->itext_langtags); + lodepng_free(info->itext_transkeys); + lodepng_free(info->itext_strings); +} + +static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + size_t i = 0; + dest->itext_keys = NULL; + dest->itext_langtags = NULL; + dest->itext_transkeys = NULL; + dest->itext_strings = NULL; + dest->itext_num = 0; + for(i = 0; i != source->itext_num; ++i) { + CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], + source->itext_transkeys[i], source->itext_strings[i])); + } + return 0; +} + +void lodepng_clear_itext(LodePNGInfo* info) { + LodePNGIText_cleanup(info); +} + +static unsigned lodepng_add_itext_sized(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str, size_t size) { + char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); + char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); + char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); + + if(new_keys) info->itext_keys = new_keys; + if(new_langtags) info->itext_langtags = new_langtags; + if(new_transkeys) info->itext_transkeys = new_transkeys; + if(new_strings) info->itext_strings = new_strings; + + if(!new_keys || !new_langtags || !new_transkeys || !new_strings) return 83; /*alloc fail*/ + + ++info->itext_num; + + info->itext_keys[info->itext_num - 1] = alloc_string(key); + info->itext_langtags[info->itext_num - 1] = alloc_string(langtag); + info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey); + info->itext_strings[info->itext_num - 1] = alloc_string_sized(str, size); + + return 0; +} + +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str) { + return lodepng_add_itext_sized(info, key, langtag, transkey, str, lodepng_strlen(str)); +} + +unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) { + if(info->iccp_defined) lodepng_clear_icc(info); + + if(profile_size == 0) return 100; /*invalid ICC profile size*/ + + info->iccp_name = alloc_string(name); + if(!info->iccp_name) return 83; /*alloc fail*/ + + info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size); + if(!info->iccp_profile) { + lodepng_free(info->iccp_name); + return 83; /*alloc fail*/ + } + + lodepng_memcpy(info->iccp_profile, profile, profile_size); + info->iccp_profile_size = profile_size; + info->iccp_defined = 1; + + return 0; /*ok*/ +} + +void lodepng_clear_icc(LodePNGInfo* info) { + string_cleanup(&info->iccp_name); + lodepng_free(info->iccp_profile); + info->iccp_profile = NULL; + info->iccp_profile_size = 0; + info->iccp_defined = 0; +} + +unsigned lodepng_set_exif(LodePNGInfo* info, const unsigned char* exif, unsigned exif_size) { + if(info->exif_defined) lodepng_clear_exif(info); + info->exif = (unsigned char*)lodepng_malloc(exif_size); + + if(!info->exif) return 83; /*alloc fail*/ + + lodepng_memcpy(info->exif, exif, exif_size); + info->exif_size = exif_size; + info->exif_defined = 1; + + return 0; /*ok*/ +} + +void lodepng_clear_exif(LodePNGInfo* info) { + lodepng_free(info->exif); + info->exif = NULL; + info->exif_size = 0; + info->exif_defined = 0; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +void lodepng_info_init(LodePNGInfo* info) { + lodepng_color_mode_init(&info->color); + info->interlace_method = 0; + info->compression_method = 0; + info->filter_method = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + info->background_defined = 0; + info->background_r = info->background_g = info->background_b = 0; + + LodePNGText_init(info); + LodePNGIText_init(info); + + info->time_defined = 0; + info->phys_defined = 0; + + info->gama_defined = 0; + info->chrm_defined = 0; + info->srgb_defined = 0; + info->iccp_defined = 0; + info->iccp_name = NULL; + info->iccp_profile = NULL; + info->cicp_defined = 0; + info->cicp_color_primaries = 0; + info->cicp_transfer_function = 0; + info->cicp_matrix_coefficients = 0; + info->cicp_video_full_range_flag = 0; + info->mdcv_defined = 0; + info->mdcv_red_x = 0; + info->mdcv_red_y = 0; + info->mdcv_green_x = 0; + info->mdcv_green_y = 0; + info->mdcv_blue_x = 0; + info->mdcv_blue_y = 0; + info->mdcv_white_x = 0; + info->mdcv_white_y = 0; + info->mdcv_max_luminance = 0; + info->mdcv_min_luminance = 0; + info->clli_defined = 0; + info->clli_max_cll = 0; + info->clli_max_fall = 0; + + info->exif_defined = 0; + info->exif = NULL; + info->exif_size = 0; + + info->sbit_defined = 0; + info->sbit_r = info->sbit_g = info->sbit_b = info->sbit_a = 0; + + LodePNGUnknownChunks_init(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +void lodepng_info_cleanup(LodePNGInfo* info) { + lodepng_color_mode_cleanup(&info->color); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + LodePNGText_cleanup(info); + LodePNGIText_cleanup(info); + + lodepng_clear_icc(info); + lodepng_clear_exif(info); + + LodePNGUnknownChunks_cleanup(info); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) { + lodepng_info_cleanup(dest); + lodepng_memcpy(dest, source, sizeof(LodePNGInfo)); + lodepng_color_mode_init(&dest->color); + CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); + CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); + if(source->iccp_defined) { + dest->iccp_defined = 0; /*the memcpy above set this to 1 while it shouldn't*/ + CERROR_TRY_RETURN(lodepng_set_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size)); + } + if(source->exif_defined) { + dest->exif_defined = 0; /*the memcpy above set this to 1 while it shouldn't*/ + CERROR_TRY_RETURN(lodepng_set_exif(dest, source->exif, source->exif_size)); + } + + LodePNGUnknownChunks_init(dest); + CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + return 0; +} + +/* ////////////////////////////////////////////////////////////////////////// */ + +/*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ +static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) { + unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ + /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ + unsigned p = index & m; + in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ + in = in << (bits * (m - p)); + if(p == 0) out[index * bits / 8u] = in; + else out[index * bits / 8u] |= in; +} + +typedef struct ColorTree ColorTree; + +/* +One node of a color tree +This is the data structure used to count the number of unique colors and to get a palette +index for a color. It's like an octree, but because the alpha channel is used too, each +node has 16 instead of 8 children. +*/ +struct ColorTree { + ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ + int index; /*the payload. Only has a meaningful value if this is in the last level*/ +}; + +static void color_tree_init(ColorTree* tree) { + lodepng_memset(tree->children, 0, 16 * sizeof(*tree->children)); + tree->index = -1; +} + +static void color_tree_cleanup(ColorTree* tree) { + int i; + for(i = 0; i != 16; ++i) { + if(tree->children[i]) { + color_tree_cleanup(tree->children[i]); + lodepng_free(tree->children[i]); + } + } +} + +/*returns -1 if color not present, its index otherwise*/ +static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + int bit = 0; + for(bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) return -1; + else tree = tree->children[i]; + } + return tree ? tree->index : -1; +} + +#ifdef LODEPNG_COMPILE_ENCODER +static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + return color_tree_get(tree, r, g, b, a) >= 0; +} +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/*color is not allowed to already exist. +Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist") +Returns error code, or 0 if ok*/ +static unsigned color_tree_add(ColorTree* tree, + unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { + int bit; + for(bit = 0; bit < 8; ++bit) { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if(!tree->children[i]) { + tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); + if(!tree->children[i]) return 83; /*alloc fail*/ + color_tree_init(tree->children[i]); + } + tree = tree->children[i]; + } + tree->index = (int)index; + return 0; +} + +/*put a pixel, given its RGBA color, into image of any color type*/ +static unsigned rgba8ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + if(mode->colortype == LCT_GREY) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if(mode->bitdepth == 8) out[i] = gray; + else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray; + else { + /*take the most significant bits of gray*/ + gray = ((unsigned)gray >> (8u - mode->bitdepth)) & ((1u << mode->bitdepth) - 1u); + addColorBits(out, i, mode->bitdepth, gray); + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + out[i * 3 + 0] = r; + out[i * 3 + 1] = g; + out[i * 3 + 2] = b; + } else { + out[i * 6 + 0] = out[i * 6 + 1] = r; + out[i * 6 + 2] = out[i * 6 + 3] = g; + out[i * 6 + 4] = out[i * 6 + 5] = b; + } + } else if(mode->colortype == LCT_PALETTE) { + int index = color_tree_get(tree, r, g, b, a); + if(index < 0) return 82; /*color not in palette*/ + if(mode->bitdepth == 8) out[i] = index; + else addColorBits(out, i, mode->bitdepth, (unsigned)index); + } else if(mode->colortype == LCT_GREY_ALPHA) { + unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ + if(mode->bitdepth == 8) { + out[i * 2 + 0] = gray; + out[i * 2 + 1] = a; + } else if(mode->bitdepth == 16) { + out[i * 4 + 0] = out[i * 4 + 1] = gray; + out[i * 4 + 2] = out[i * 4 + 3] = a; + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + out[i * 4 + 0] = r; + out[i * 4 + 1] = g; + out[i * 4 + 2] = b; + out[i * 4 + 3] = a; + } else { + out[i * 8 + 0] = out[i * 8 + 1] = r; + out[i * 8 + 2] = out[i * 8 + 3] = g; + out[i * 8 + 4] = out[i * 8 + 5] = b; + out[i * 8 + 6] = out[i * 8 + 7] = a; + } + } + + return 0; /*no error*/ +} + +/*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ +static void rgba16ToPixel(unsigned char* out, size_t i, + const LodePNGColorMode* mode, + unsigned short r, unsigned short g, unsigned short b, unsigned short a) { + if(mode->colortype == LCT_GREY) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 2 + 0] = (gray >> 8) & 255; + out[i * 2 + 1] = gray & 255; + } else if(mode->colortype == LCT_RGB) { + out[i * 6 + 0] = (r >> 8) & 255; + out[i * 6 + 1] = r & 255; + out[i * 6 + 2] = (g >> 8) & 255; + out[i * 6 + 3] = g & 255; + out[i * 6 + 4] = (b >> 8) & 255; + out[i * 6 + 5] = b & 255; + } else if(mode->colortype == LCT_GREY_ALPHA) { + unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ + out[i * 4 + 0] = (gray >> 8) & 255; + out[i * 4 + 1] = gray & 255; + out[i * 4 + 2] = (a >> 8) & 255; + out[i * 4 + 3] = a & 255; + } else if(mode->colortype == LCT_RGBA) { + out[i * 8 + 0] = (r >> 8) & 255; + out[i * 8 + 1] = r & 255; + out[i * 8 + 2] = (g >> 8) & 255; + out[i * 8 + 3] = g & 255; + out[i * 8 + 4] = (b >> 8) & 255; + out[i * 8 + 5] = b & 255; + out[i * 8 + 6] = (a >> 8) & 255; + out[i * 8 + 7] = a & 255; + } +} + +/*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ +static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, + unsigned char* b, unsigned char* a, + const unsigned char* in, size_t i, + const LodePNGColorMode* mode) { + if(mode->colortype == LCT_GREY) { + if(mode->bitdepth == 8) { + *r = *g = *b = in[i]; + if(mode->key_defined && *r == mode->key_r) *a = 0; + else *a = 255; + } else if(mode->bitdepth == 16) { + *r = *g = *b = in[i * 2 + 0]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 255; + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = i * mode->bitdepth; + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + *r = *g = *b = (value * 255) / highest; + if(mode->key_defined && value == mode->key_r) *a = 0; + else *a = 255; + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; + if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; + else *a = 255; + } else { + *r = in[i * 6 + 0]; + *g = in[i * 6 + 2]; + *b = in[i * 6 + 4]; + if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 255; + } + } else if(mode->colortype == LCT_PALETTE) { + unsigned index; + if(mode->bitdepth == 8) index = in[i]; + else { + size_t j = i * mode->bitdepth; + index = readBitsFromReversedStream(&j, in, mode->bitdepth); + } + /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ + *r = mode->palette[index * 4 + 0]; + *g = mode->palette[index * 4 + 1]; + *b = mode->palette[index * 4 + 2]; + *a = mode->palette[index * 4 + 3]; + } else if(mode->colortype == LCT_GREY_ALPHA) { + if(mode->bitdepth == 8) { + *r = *g = *b = in[i * 2 + 0]; + *a = in[i * 2 + 1]; + } else { + *r = *g = *b = in[i * 4 + 0]; + *a = in[i * 4 + 2]; + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + *r = in[i * 4 + 0]; + *g = in[i * 4 + 1]; + *b = in[i * 4 + 2]; + *a = in[i * 4 + 3]; + } else { + *r = in[i * 8 + 0]; + *g = in[i * 8 + 2]; + *b = in[i * 8 + 4]; + *a = in[i * 8 + 6]; + } + } +} + +/*Similar to getPixelColorRGBA8, but with all the for loops inside of the color +mode test cases, optimized to convert the colors much faster, when converting +to the common case of RGBA with 8 bit per channel. buffer must be RGBA with +enough memory.*/ +static void getPixelColorsRGBA8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, + const unsigned char* LODEPNG_RESTRICT in, + const LodePNGColorMode* mode) { + unsigned num_channels = 4; + size_t i; + if(mode->colortype == LCT_GREY) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i]; + buffer[3] = 255; + } + if(mode->key_defined) { + buffer -= numpixels * num_channels; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + if(buffer[0] == mode->key_r) buffer[3] = 0; + } + } + } else if(mode->bitdepth == 16) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; + } + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; + } + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + lodepng_memcpy(buffer, &in[i * 3], 3); + buffer[3] = 255; + } + if(mode->key_defined) { + buffer -= numpixels * num_channels; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + if(buffer[0] == mode->key_r && buffer[1]== mode->key_g && buffer[2] == mode->key_b) buffer[3] = 0; + } + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + buffer[3] = mode->key_defined + && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; + } + } + } else if(mode->colortype == LCT_PALETTE) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = in[i]; + /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ + lodepng_memcpy(buffer, &mode->palette[index * 4], 4); + } + } else { + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); + /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ + lodepng_memcpy(buffer, &mode->palette[index * 4], 4); + } + } + } else if(mode->colortype == LCT_GREY_ALPHA) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + buffer[3] = in[i * 2 + 1]; + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + buffer[3] = in[i * 4 + 2]; + } + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + lodepng_memcpy(buffer, in, numpixels * 4); + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + buffer[3] = in[i * 8 + 6]; + } + } + } +} + +/*Similar to getPixelColorsRGBA8, but with 3-channel RGB output.*/ +static void getPixelColorsRGB8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, + const unsigned char* LODEPNG_RESTRICT in, + const LodePNGColorMode* mode) { + const unsigned num_channels = 3; + size_t i; + if(mode->colortype == LCT_GREY) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i]; + } + } else if(mode->bitdepth == 16) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + } + } else { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + } + } + } else if(mode->colortype == LCT_RGB) { + if(mode->bitdepth == 8) { + lodepng_memcpy(buffer, in, numpixels * 3); + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + } + } + } else if(mode->colortype == LCT_PALETTE) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = in[i]; + /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ + lodepng_memcpy(buffer, &mode->palette[index * 4], 3); + } + } else { + size_t j = 0; + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); + /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ + lodepng_memcpy(buffer, &mode->palette[index * 4], 3); + } + } + } else if(mode->colortype == LCT_GREY_ALPHA) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + } + } + } else if(mode->colortype == LCT_RGBA) { + if(mode->bitdepth == 8) { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + lodepng_memcpy(buffer, &in[i * 4], 3); + } + } else { + for(i = 0; i != numpixels; ++i, buffer += num_channels) { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + } + } + } +} + +/*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with +given color type, but the given color type must be 16-bit itself.*/ +static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, + const unsigned char* in, size_t i, const LodePNGColorMode* mode) { + if(mode->colortype == LCT_GREY) { + *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; + if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; + else *a = 65535; + } else if(mode->colortype == LCT_RGB) { + *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; + if(mode->key_defined + && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r + && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g + && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; + else *a = 65535; + } else if(mode->colortype == LCT_GREY_ALPHA) { + *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; + } else if(mode->colortype == LCT_RGBA) { + *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; + } +} + +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h) { + size_t i; + ColorTree tree; + size_t numpixels = (size_t)w * (size_t)h; + unsigned error = 0; + + if(mode_in->colortype == LCT_PALETTE && !mode_in->palette) { + return 107; /* error: must provide palette if input mode is palette */ + } + + if(lodepng_color_mode_equal(mode_out, mode_in)) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + lodepng_memcpy(out, in, numbytes); + return 0; + } + + if(mode_out->colortype == LCT_PALETTE) { + size_t palettesize = mode_out->palettesize; + const unsigned char* palette = mode_out->palette; + size_t palsize = (size_t)1u << mode_out->bitdepth; + /*if the user specified output palette but did not give the values, assume + they want the values of the input color type (assuming that one is palette). + Note that we never create a new palette ourselves.*/ + if(palettesize == 0) { + palettesize = mode_in->palettesize; + palette = mode_in->palette; + /*if the input was also palette with same bitdepth, then the color types are also + equal, so copy literally. This to preserve the exact indices that were in the PNG + even in case there are duplicate colors in the palette.*/ + if(mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + lodepng_memcpy(out, in, numbytes); + return 0; + } + } + if(palettesize < palsize) palsize = palettesize; + color_tree_init(&tree); + for(i = 0; i != palsize; ++i) { + const unsigned char* p = &palette[i * 4]; + error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i); + if(error) break; + } + } + + if(!error) { + if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { + for(i = 0; i != numpixels; ++i) { + unsigned short r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + rgba16ToPixel(out, i, mode_out, r, g, b, a); + } + } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { + getPixelColorsRGBA8(out, numpixels, in, mode_in); + } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { + getPixelColorsRGB8(out, numpixels, in, mode_in); + } else { + unsigned char r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + if(error) break; + } + } + } + + if(mode_out->colortype == LCT_PALETTE) { + color_tree_cleanup(&tree); + } + + return error; +} + + +/* Converts a single rgb color without alpha from one type to another, color bits truncated to +their bitdepth. In case of single channel (gray or palette), only the r channel is used. Slow +function, do not use to process all pixels of an image. Alpha channel not supported on purpose: +this is for bKGD, supporting alpha may prevent it from finding a color in the palette, from the +specification it looks like bKGD should ignore the alpha values of the palette since it can use +any palette index but doesn't have an alpha channel. Idem with ignoring color key. */ +unsigned lodepng_convert_rgb( + unsigned* r_out, unsigned* g_out, unsigned* b_out, + unsigned r_in, unsigned g_in, unsigned b_in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in) { + unsigned r = 0, g = 0, b = 0; + unsigned mul = 65535 / ((1u << mode_in->bitdepth) - 1u); /*65535, 21845, 4369, 257, 1*/ + unsigned shift = 16 - mode_out->bitdepth; + + if(mode_in->colortype == LCT_GREY || mode_in->colortype == LCT_GREY_ALPHA) { + r = g = b = r_in * mul; + } else if(mode_in->colortype == LCT_RGB || mode_in->colortype == LCT_RGBA) { + r = r_in * mul; + g = g_in * mul; + b = b_in * mul; + } else if(mode_in->colortype == LCT_PALETTE) { + if(r_in >= mode_in->palettesize) return 82; + r = mode_in->palette[r_in * 4 + 0] * 257u; + g = mode_in->palette[r_in * 4 + 1] * 257u; + b = mode_in->palette[r_in * 4 + 2] * 257u; + } else { + return 31; + } + + /* now convert to output format */ + if(mode_out->colortype == LCT_GREY || mode_out->colortype == LCT_GREY_ALPHA) { + *r_out = r >> shift ; + } else if(mode_out->colortype == LCT_RGB || mode_out->colortype == LCT_RGBA) { + *r_out = r >> shift ; + *g_out = g >> shift ; + *b_out = b >> shift ; + } else if(mode_out->colortype == LCT_PALETTE) { + unsigned i; + /* a 16-bit color cannot be in the palette */ + if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255)) return 82; + for(i = 0; i < mode_out->palettesize; i++) { + unsigned j = i * 4; + if((r >> 8) == mode_out->palette[j + 0] && (g >> 8) == mode_out->palette[j + 1] && + (b >> 8) == mode_out->palette[j + 2]) { + *r_out = i; + return 0; + } + } + return 82; + } else { + return 31; + } + + return 0; +} + +#ifdef LODEPNG_COMPILE_ENCODER + +void lodepng_color_stats_init(LodePNGColorStats* stats) { + /*stats*/ + stats->colored = 0; + stats->key = 0; + stats->key_r = stats->key_g = stats->key_b = 0; + stats->alpha = 0; + stats->numcolors = 0; + stats->bits = 1; + stats->numpixels = 0; + /*settings*/ + stats->allow_palette = 1; + stats->allow_greyscale = 1; +} + +/*function used for debug purposes with C++*/ +/*void printColorStats(LodePNGColorStats* p) { + std::cout << "colored: " << (int)p->colored << ", "; + std::cout << "key: " << (int)p->key << ", "; + std::cout << "key_r: " << (int)p->key_r << ", "; + std::cout << "key_g: " << (int)p->key_g << ", "; + std::cout << "key_b: " << (int)p->key_b << ", "; + std::cout << "alpha: " << (int)p->alpha << ", "; + std::cout << "numcolors: " << (int)p->numcolors << ", "; + std::cout << "bits: " << (int)p->bits << std::endl; +}*/ + +/*Returns how many bits needed to represent given value (max 8 bit)*/ +static unsigned getValueRequiredBits(unsigned char value) { + if(value == 0 || value == 255) return 1; + /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ + if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; + return 8; +} + +/*stats must already have been inited. */ +unsigned lodepng_compute_color_stats(LodePNGColorStats* stats, + const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* mode_in) { + size_t i; + ColorTree tree; + size_t numpixels = (size_t)w * (size_t)h; + unsigned error = 0; + + /* mark things as done already if it would be impossible to have a more expensive case */ + unsigned colored_done = lodepng_is_greyscale_type(mode_in) ? 1 : 0; + unsigned alpha_done = lodepng_can_have_alpha(mode_in) ? 0 : 1; + unsigned numcolors_done = 0; + unsigned bpp = lodepng_get_bpp(mode_in); + unsigned bits_done = (stats->bits == 1 && bpp == 1) ? 1 : 0; + unsigned sixteen = 0; /* whether the input image is 16 bit */ + unsigned maxnumcolors = 257; + if(bpp <= 8) maxnumcolors = LODEPNG_MIN(257, stats->numcolors + (1u << bpp)); + + stats->numpixels += numpixels; + + /*if palette not allowed, no need to compute numcolors*/ + if(!stats->allow_palette) numcolors_done = 1; + + color_tree_init(&tree); + + /*If the stats was already filled in from previous data, fill its palette in tree + and mark things as done already if we know they are the most expensive case already*/ + if(stats->alpha) alpha_done = 1; + if(stats->colored) colored_done = 1; + if(stats->bits == 16) numcolors_done = 1; + if(stats->bits >= bpp) bits_done = 1; + if(stats->numcolors >= maxnumcolors) numcolors_done = 1; + + if(!numcolors_done) { + for(i = 0; i < stats->numcolors; i++) { + const unsigned char* color = &stats->palette[i * 4]; + error = color_tree_add(&tree, color[0], color[1], color[2], color[3], (unsigned)i); + if(error) goto cleanup; + } + } + + /*Check if the 16-bit input is truly 16-bit*/ + if(mode_in->bitdepth == 16 && !sixteen) { + unsigned short r = 0, g = 0, b = 0, a = 0; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || + (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ { + stats->bits = 16; + sixteen = 1; + bits_done = 1; + numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ + break; + } + } + } + + if(sixteen) { + unsigned short r = 0, g = 0, b = 0, a = 0; + + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + + if(!colored_done && (r != g || r != b)) { + stats->colored = 1; + colored_done = 1; + } + + if(!alpha_done) { + unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); + if(a != 65535 && (a != 0 || (stats->key && !matchkey))) { + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } else if(a == 0 && !stats->alpha && !stats->key) { + stats->key = 1; + stats->key_r = r; + stats->key_g = g; + stats->key_b = b; + } else if(a == 65535 && stats->key && matchkey) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } + } + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(stats->key && !stats->alpha) { + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + } + } + } + } else /* < 16-bit */ { + unsigned char r = 0, g = 0, b = 0, a = 0; + unsigned char pr = 0, pg = 0, pb = 0, pa = 0; + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + + /*skip if color same as before, this speeds up large non-photographic + images with many same colors by avoiding 'color_tree_has' below */ + if(i != 0 && r == pr && g == pg && b == pb && a == pa) continue; + pr = r; + pg = g; + pb = b; + pa = a; + + if(!bits_done && stats->bits < 8) { + /*only r is checked, < 8 bits is only relevant for grayscale*/ + unsigned bits = getValueRequiredBits(r); + if(bits > stats->bits) stats->bits = bits; + } + bits_done = (stats->bits >= bpp); + + if(!colored_done && (r != g || r != b)) { + stats->colored = 1; + colored_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ + } + + if(!alpha_done) { + unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); + if(a != 255 && (a != 0 || (stats->key && !matchkey))) { + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } else if(a == 0 && !stats->alpha && !stats->key) { + stats->key = 1; + stats->key_r = r; + stats->key_g = g; + stats->key_b = b; + } else if(a == 255 && stats->key && matchkey) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + + if(!numcolors_done) { + if(!color_tree_has(&tree, r, g, b, a)) { + error = color_tree_add(&tree, r, g, b, a, stats->numcolors); + if(error) goto cleanup; + if(stats->numcolors < 256) { + unsigned char* p = stats->palette; + unsigned n = stats->numcolors; + p[n * 4 + 0] = r; + p[n * 4 + 1] = g; + p[n * 4 + 2] = b; + p[n * 4 + 3] = a; + } + ++stats->numcolors; + numcolors_done = stats->numcolors >= maxnumcolors; + } + } + + if(alpha_done && numcolors_done && colored_done && bits_done) break; + } + + if(stats->key && !stats->alpha) { + for(i = 0; i != numpixels; ++i) { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + stats->alpha = 1; + stats->key = 0; + alpha_done = 1; + if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } + } + + /*make the stats's key always 16-bit for consistency - repeat each byte twice*/ + stats->key_r += (stats->key_r << 8); + stats->key_g += (stats->key_g << 8); + stats->key_b += (stats->key_b << 8); + } + +cleanup: + color_tree_cleanup(&tree); + return error; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*Adds a single color to the color stats. The stats must already have been inited. The color must be given as 16-bit +(with 2 bytes repeating for 8-bit and 65535 for opaque alpha channel). This function is expensive, do not call it for +all pixels of an image but only for a few additional values. */ +static unsigned lodepng_color_stats_add(LodePNGColorStats* stats, + unsigned r, unsigned g, unsigned b, unsigned a) { + unsigned error = 0; + unsigned char image[8]; + LodePNGColorMode mode; + lodepng_color_mode_init(&mode); + image[0] = r >> 8; image[1] = r; image[2] = g >> 8; image[3] = g; + image[4] = b >> 8; image[5] = b; image[6] = a >> 8; image[7] = a; + mode.bitdepth = 16; + mode.colortype = LCT_RGBA; + error = lodepng_compute_color_stats(stats, image, 1, 1, &mode); + lodepng_color_mode_cleanup(&mode); + return error; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*Computes a minimal PNG color model that can contain all colors as indicated by the stats. +The stats should be computed with lodepng_compute_color_stats. +mode_in is raw color profile of the image the stats were computed on, to copy palette order from when relevant. +Minimal PNG color model means the color type and bit depth that gives smallest amount of bits in the output image, +e.g. gray if only grayscale pixels, palette if less than 256 colors, color key if only single transparent color, ... +This is used if auto_convert is enabled (it is by default). +*/ +static unsigned auto_choose_color(LodePNGColorMode* mode_out, + const LodePNGColorMode* mode_in, + const LodePNGColorStats* stats) { + unsigned error = 0; + unsigned palettebits; + size_t i, n; + size_t numpixels = stats->numpixels; + unsigned palette_ok, gray_ok; + + unsigned alpha = stats->alpha; + unsigned key = stats->key; + unsigned bits = stats->bits; + + mode_out->key_defined = 0; + + if(key && numpixels <= 16) { + alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + key = 0; + if(bits < 8) bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + + gray_ok = !stats->colored; + if(!stats->allow_greyscale) gray_ok = 0; + if(!gray_ok && bits < 8) bits = 8; + + n = stats->numcolors; + palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); + palette_ok = n <= 256 && bits <= 8 && n != 0; /*n==0 means likely numcolors wasn't computed*/ + if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ + if(gray_ok && !alpha && bits <= palettebits) palette_ok = 0; /*gray is less overhead*/ + if(!stats->allow_palette) palette_ok = 0; + + if(palette_ok) { + const unsigned char* p = stats->palette; + lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ + for(i = 0; i != stats->numcolors; ++i) { + error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); + if(error) break; + } + + mode_out->colortype = LCT_PALETTE; + mode_out->bitdepth = palettebits; + + if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize + && mode_in->bitdepth == mode_out->bitdepth) { + /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ + lodepng_color_mode_cleanup(mode_out); /*clears palette, keeps the above set colortype and bitdepth fields as-is*/ + lodepng_color_mode_copy(mode_out, mode_in); + } + } else /*8-bit or 16-bit per channel*/ { + mode_out->bitdepth = bits; + mode_out->colortype = alpha ? (gray_ok ? LCT_GREY_ALPHA : LCT_RGBA) + : (gray_ok ? LCT_GREY : LCT_RGB); + if(key) { + unsigned mask = (1u << mode_out->bitdepth) - 1u; /*stats always uses 16-bit, mask converts it*/ + mode_out->key_r = stats->key_r & mask; + mode_out->key_g = stats->key_g & mask; + mode_out->key_b = stats->key_b & mask; + mode_out->key_defined = 1; + } + } + + return error; +} + +#endif /* #ifdef LODEPNG_COMPILE_ENCODER */ + +/*Paeth predictor, used by PNG filter type 4*/ +static unsigned char paethPredictor(unsigned char a, unsigned char b, unsigned char c) { + /* the subtractions of unsigned char cast it to a signed type. + With gcc, short is faster than int, with clang int is as fast (as of april 2023)*/ + short pa = (b - c) < 0 ? -(b - c) : (b - c); + short pb = (a - c) < 0 ? -(a - c) : (a - c); + /* writing it out like this compiles to something faster than introducing a temp variable*/ + short pc = (a + b - c - c) < 0 ? -(a + b - c - c) : (a + b - c - c); + /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */ + if(pb < pa) { a = b; pa = pb; } + return (pc < pa) ? c : a; +} + +/*shared values used by multiple Adam7 related functions*/ + +static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ +static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ +static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ +static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ + +/* +Outputs various dimensions and positions in the image related to the Adam7 reduced images. +passw: output containing the width of the 7 passes +passh: output containing the height of the 7 passes +filter_passstart: output containing the index of the start and end of each + reduced image with filter bytes +padded_passstart output containing the index of the start and end of each + reduced image when without filter bytes but with padded scanlines +passstart: output containing the index of the start and end of each reduced + image without padding between scanlines, but still padding between the images +w, h: width and height of non-interlaced image +bpp: bits per pixel +"padded" is only relevant if bpp is less than 8 and a scanline or image does not + end at a full byte +*/ +static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], + size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) { + /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ + unsigned i; + + /*calculate width and height in pixels of each pass*/ + for(i = 0; i != 7; ++i) { + passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; + passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; + if(passw[i] == 0) passh[i] = 0; + if(passh[i] == 0) passw[i] = 0; + } + + filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; + for(i = 0; i != 7; ++i) { + /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ + filter_passstart[i + 1] = filter_passstart[i] + + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0); + /*bits padded if needed to fill full byte at end of each scanline*/ + padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u); + /*only padded at end of reduced image*/ + passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u; + } +} + +#ifdef LODEPNG_COMPILE_DECODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Decoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + +/*read the information from the header and store it in the LodePNGInfo. return value is error*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, + const unsigned char* in, size_t insize) { + unsigned width, height; + LodePNGInfo* info = &state->info_png; + if(insize == 0 || in == 0) { + CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ + } + if(insize < 33) { + CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ + } + + /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ + /* TODO: remove this. One should use a new LodePNGState for new sessions */ + lodepng_info_cleanup(info); + lodepng_info_init(info); + + if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 + || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { + CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ + } + if(lodepng_chunk_length(in + 8) != 13) { + CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ + } + if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { + CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ + } + + /*read the values given in the header*/ + width = lodepng_read32bitInt(&in[16]); + height = lodepng_read32bitInt(&in[20]); + /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/ + if(w) *w = width; + if(h) *h = height; + info->color.bitdepth = in[24]; + info->color.colortype = (LodePNGColorType)in[25]; + info->compression_method = in[26]; + info->filter_method = in[27]; + info->interlace_method = in[28]; + + /*errors returned only after the parsing so other values are still output*/ + + /*error: invalid image size*/ + if(width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93); + /*error: invalid colortype or bitdepth combination*/ + state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); + if(state->error) return state->error; + /*error: only compression method 0 is allowed in the specification*/ + if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); + /*error: only filter method 0 is allowed in the specification*/ + if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); + /*error: only interlace methods 0 and 1 exist in the specification*/ + if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); + + if(!state->decoder.ignore_crc) { + unsigned crc = lodepng_read32bitInt(&in[29]); + unsigned checksum = lodepng_crc32(&in[12], 17); + if(crc != checksum) { + CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ + } + } + + return state->error; +} + +static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, + size_t bytewidth, unsigned char filterType, size_t length) { + /* + For PNG filter method 0 + unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, + the filter works byte per byte (bytewidth = 1) + precon is the previous unfiltered scanline, recon the result, scanline the current one + the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead + recon and scanline MAY be the same memory address! precon must be disjoint. + */ + + size_t i; + switch(filterType) { + case 0: + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + break; + case 1: { + size_t j = 0; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j]; + break; + } + case 2: + if(precon) { + for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; + } else { + for(i = 0; i != length; ++i) recon[i] = scanline[i]; + } + break; + case 3: + if(precon) { + size_t j = 0; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u); + /* Unroll independent paths of this predictor. A 6x and 8x version is also possible but that adds + too much code. Whether this speeds up anything depends on compiler and settings. */ + if(bytewidth >= 4) { + for(; i + 3 < length; i += 4, j += 4) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + recon[i + 2] = s2 + ((r2 + p2) >> 1u); + recon[i + 3] = s3 + ((r3 + p3) >> 1u); + } + } else if(bytewidth >= 3) { + for(; i + 2 < length; i += 3, j += 3) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + recon[i + 2] = s2 + ((r2 + p2) >> 1u); + } + } else if(bytewidth >= 2) { + for(; i + 1 < length; i += 2, j += 2) { + unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; + unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; + unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; + recon[i + 0] = s0 + ((r0 + p0) >> 1u); + recon[i + 1] = s1 + ((r1 + p1) >> 1u); + } + } + for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u); + } else { + size_t j = 0; + for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; + for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u); + } + break; + case 4: + if(precon) { + /* Unroll independent paths of this predictor. Whether this speeds up + anything depends on compiler and settings. */ + if(bytewidth == 8) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0; + unsigned char a6, b6 = 0, c6, d6 = 0, a7, b7 = 0, c7, d7 = 0; + for(i = 0; i + 7 < length; i += 8) { + c0 = b0; c1 = b1; c2 = b2; c3 = b3; + c4 = b4; c5 = b5; c6 = b6; c7 = b7; + b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; b3 = precon[i + 3]; + b4 = precon[i + 4]; b5 = precon[i + 5]; b6 = precon[i + 6]; b7 = precon[i + 7]; + a0 = d0; a1 = d1; a2 = d2; a3 = d3; + a4 = d4; a5 = d5; a6 = d6; a7 = d7; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + d4 = scanline[i + 4] + paethPredictor(a4, b4, c4); + d5 = scanline[i + 5] + paethPredictor(a5, b5, c5); + d6 = scanline[i + 6] + paethPredictor(a6, b6, c6); + d7 = scanline[i + 7] + paethPredictor(a7, b7, c7); + recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; recon[i + 3] = d3; + recon[i + 4] = d4; recon[i + 5] = d5; recon[i + 6] = d6; recon[i + 7] = d7; + } + } else if(bytewidth == 6) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0; + for(i = 0; i + 5 < length; i += 6) { + c0 = b0; c1 = b1; c2 = b2; + c3 = b3; c4 = b4; c5 = b5; + b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; + b3 = precon[i + 3]; b4 = precon[i + 4]; b5 = precon[i + 5]; + a0 = d0; a1 = d1; a2 = d2; + a3 = d3; a4 = d4; a5 = d5; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + d4 = scanline[i + 4] + paethPredictor(a4, b4, c4); + d5 = scanline[i + 5] + paethPredictor(a5, b5, c5); + recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; + recon[i + 3] = d3; recon[i + 4] = d4; recon[i + 5] = d5; + } + } else if(bytewidth == 4) { + unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0; + for(i = 0; i + 3 < length; i += 4) { + c0 = b0; c1 = b1; c2 = b2; c3 = b3; + b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; b3 = precon[i + 3]; + a0 = d0; a1 = d1; a2 = d2; a3 = d3; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + d3 = scanline[i + 3] + paethPredictor(a3, b3, c3); + recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; recon[i + 3] = d3; + } + } else if(bytewidth == 3) { + unsigned char a0, b0 = 0, c0, d0 = 0; + unsigned char a1, b1 = 0, c1, d1 = 0; + unsigned char a2, b2 = 0, c2, d2 = 0; + for(i = 0; i + 2 < length; i += 3) { + c0 = b0; c1 = b1; c2 = b2; + b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; + a0 = d0; a1 = d1; a2 = d2; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + d2 = scanline[i + 2] + paethPredictor(a2, b2, c2); + recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; + } + } else if(bytewidth == 2) { + unsigned char a0, b0 = 0, c0, d0 = 0; + unsigned char a1, b1 = 0, c1, d1 = 0; + for(i = 0; i + 1 < length; i += 2) { + c0 = b0; c1 = b1; + b0 = precon[i + 0]; + b1 = precon[i + 1]; + a0 = d0; a1 = d1; + d0 = scanline[i + 0] + paethPredictor(a0, b0, c0); + d1 = scanline[i + 1] + paethPredictor(a1, b1, c1); + recon[i + 0] = d0; + recon[i + 1] = d1; + } + } else if(bytewidth == 1) { + unsigned char a, b = 0, c, d = 0; + for(i = 0; i != length; ++i) { + c = b; + b = precon[i]; + a = d; + d = scanline[i] + paethPredictor(a, b, c); + recon[i] = d; + } + } else { + /* Normally not a possible case, but this would handle it correctly */ + for(i = 0; i != bytewidth; ++i) { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + } + /* finish any remaining bytes */ + for(; i != length; ++i) { + recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); + } + } else { + size_t j = 0; + for(i = 0; i != bytewidth; ++i) { + recon[i] = scanline[i]; + } + for(i = bytewidth; i != length; ++i, ++j) { + /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ + recon[i] = (scanline[i] + recon[j]); + } + } + break; + default: return 36; /*error: invalid filter type given*/ + } + return 0; +} + +static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + /* + For PNG filter method 0 + this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) + out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline + w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel + in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) + */ + + unsigned y; + unsigned char* prevline = 0; + + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7u) / 8u; + /*the width of a scanline in bytes, not including the filter type*/ + size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u; + + for(y = 0; y < h; ++y) { + size_t outindex = linebytes * y; + size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + unsigned char filterType = in[inindex]; + + CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); + + prevline = &out[outindex]; + } + + return 0; +} + +/* +in: Adam7 interlaced image, with no padding bits between scanlines, but between + reduced images so that each reduced image starts at a byte. +out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h +bpp: bits per pixel +out has the following size in bits: w * h * bpp. +in is possibly bigger due to padding bits between reduced images. +out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation +(because that's likely a little bit faster) +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + size_t bytewidth = bpp / 8u; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; + size_t pixeloutstart = ((ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * (size_t)w + + ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bytewidth; + for(b = 0; b < bytewidth; ++b) { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + obp = (ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bpp; + for(b = 0; b < bpp; ++b) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + +static void removePaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) { + /* + After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need + to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers + for the Adam7 code, the color convert code and the output to the user. + in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must + have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits + also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 + only useful if (ilinebits - olinebits) is a value in the range 1..7 + */ + unsigned y; + size_t diff = ilinebits - olinebits; + size_t ibp = 0, obp = 0; /*input and output bit pointers*/ + for(y = 0; y < h; ++y) { + size_t x; + for(x = 0; x < olinebits; ++x) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + ibp += diff; + } +} + +/*out must be buffer big enough to contain full image, and in must contain the full decompressed data from +the IDAT chunks (with filter index bytes and possible padding bits) +return value is error*/ +static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, + unsigned w, unsigned h, const LodePNGInfo* info_png) { + /* + This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. + Steps: + *) if no Adam7: 1) unfilter 2) remove padding bits (= possible extra bits per scanline if bpp < 8) + *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace + NOTE: the in buffer will be overwritten with intermediate data! + */ + unsigned bpp = lodepng_get_bpp(&info_png->color); + if(bpp == 0) return 31; /*error: invalid colortype*/ + + if(info_png->interlace_method == 0) { + if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { + CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); + removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h); + } + /*we can immediately filter into the out buffer, no other steps needed*/ + else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); + } else /*interlace_method is 1 (Adam7)*/ { + unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + for(i = 0; i != 7; ++i) { + CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); + /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, + move bytes instead of bits or move not at all*/ + if(bpp < 8) { + /*remove padding bits in scanlines; after this there still may be padding + bits between the different reduced images: each reduced image still starts nicely at a byte*/ + removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, + ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]); + } + } + + Adam7_deinterlace(out, in, w, h, bpp); + } + + return 0; +} + +static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { + unsigned pos = 0, i; + color->palettesize = chunkLength / 3u; + if(color->palettesize == 0 || color->palettesize > 256) return 38; /*error: palette too small or big*/ + lodepng_color_mode_alloc_palette(color); + if(!color->palette && color->palettesize) { + color->palettesize = 0; + return 83; /*alloc fail*/ + } + + for(i = 0; i != color->palettesize; ++i) { + color->palette[4 * i + 0] = data[pos++]; /*R*/ + color->palette[4 * i + 1] = data[pos++]; /*G*/ + color->palette[4 * i + 2] = data[pos++]; /*B*/ + color->palette[4 * i + 3] = 255; /*alpha*/ + } + + return 0; /* OK */ +} + +static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { + unsigned i; + if(color->colortype == LCT_PALETTE) { + /*error: more alpha values given than there are palette entries*/ + if(chunkLength > color->palettesize) return 39; + + for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; + } else if(color->colortype == LCT_GREY) { + /*error: this chunk must be 2 bytes for grayscale image*/ + if(chunkLength != 2) return 30; + + color->key_defined = 1; + color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; + } else if(color->colortype == LCT_RGB) { + /*error: this chunk must be 6 bytes for RGB image*/ + if(chunkLength != 6) return 41; + + color->key_defined = 1; + color->key_r = 256u * data[0] + data[1]; + color->key_g = 256u * data[2] + data[3]; + color->key_b = 256u * data[4] + data[5]; + } + else return 42; /*error: tRNS chunk not allowed for other color models*/ + + return 0; /* OK */ +} + + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*background color chunk (bKGD)*/ +static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(info->color.colortype == LCT_PALETTE) { + /*error: this chunk must be 1 byte for indexed color image*/ + if(chunkLength != 1) return 43; + + /*error: invalid palette index, or maybe this chunk appeared before PLTE*/ + if(data[0] >= info->color.palettesize) return 103; + + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = data[0]; + } else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { + /*error: this chunk must be 2 bytes for grayscale image*/ + if(chunkLength != 2) return 44; + + /*the values are truncated to bitdepth in the PNG file*/ + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { + /*error: this chunk must be 6 bytes for grayscale image*/ + if(chunkLength != 6) return 45; + + /*the values are truncated to bitdepth in the PNG file*/ + info->background_defined = 1; + info->background_r = 256u * data[0] + data[1]; + info->background_g = 256u * data[2] + data[3]; + info->background_b = 256u * data[4] + data[5]; + } + + return 0; /* OK */ +} + +/*text chunk (tEXt)*/ +static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + char *key = 0, *str = 0; + + while(!error) /*not really a while loop, only used to break on error*/ { + unsigned length, string2_begin; + + length = 0; + while(length < chunkLength && data[length] != 0) ++length; + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(key, data, length); + key[length] = 0; + + string2_begin = length + 1; /*skip keyword null terminator*/ + + length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin); + str = (char*)lodepng_malloc(length + 1); + if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(str, data + string2_begin, length); + str[length] = 0; + + error = lodepng_add_text(info, key, str); + + break; + } + + lodepng_free(key); + lodepng_free(str); + + return error; +} + +/*compressed text chunk (zTXt)*/ +static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + + /*copy the object to change parameters in it*/ + LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; + + unsigned length, string2_begin; + char *key = 0; + unsigned char* str = 0; + size_t size = 0; + + while(!error) /*not really a while loop, only used to break on error*/ { + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(key, data, length); + key[length] = 0; + + if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + string2_begin = length + 2; + if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + + length = (unsigned)chunkLength - string2_begin; + zlibsettings.max_output_size = decoder->max_text_size; + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&str, &size, 0, &data[string2_begin], + length, &zlibsettings); + /*error: compressed text larger than decoder->max_text_size*/ + if(error && size > zlibsettings.max_output_size) error = 112; + if(error) break; + error = lodepng_add_text_sized(info, key, (char*)str, size); + break; + } + + lodepng_free(key); + lodepng_free(str); + + return error; +} + +/*international text chunk (iTXt)*/ +static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + unsigned i; + + /*copy the object to change parameters in it*/ + LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; + + unsigned length, begin, compressed; + char *key = 0, *langtag = 0, *transkey = 0; + + while(!error) /*not really a while loop, only used to break on error*/ { + /*Quick check if the chunk length isn't too small. Even without check + it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ + if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ + + /*read the key*/ + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ + if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + + key = (char*)lodepng_malloc(length + 1); + if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(key, data, length); + key[length] = 0; + + /*read the compression method*/ + compressed = data[length + 1]; + if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + + /*even though it's not allowed by the standard, no error is thrown if + there's no null termination char, if the text is empty for the next 3 texts*/ + + /*read the langtag*/ + begin = length + 3; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + langtag = (char*)lodepng_malloc(length + 1); + if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(langtag, data + begin, length); + langtag[length] = 0; + + /*read the transkey*/ + begin += length + 1; + length = 0; + for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; + + transkey = (char*)lodepng_malloc(length + 1); + if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ + + lodepng_memcpy(transkey, data + begin, length); + transkey[length] = 0; + + /*read the actual text*/ + begin += length + 1; + + length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin; + + if(compressed) { + unsigned char* str = 0; + size_t size = 0; + zlibsettings.max_output_size = decoder->max_text_size; + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&str, &size, 0, &data[begin], + length, &zlibsettings); + /*error: compressed text larger than decoder->max_text_size*/ + if(error && size > zlibsettings.max_output_size) error = 112; + if(!error) error = lodepng_add_itext_sized(info, key, langtag, transkey, (char*)str, size); + lodepng_free(str); + } else { + error = lodepng_add_itext_sized(info, key, langtag, transkey, (const char*)(data + begin), length); + } + + break; + } + + lodepng_free(key); + lodepng_free(langtag); + lodepng_free(transkey); + + return error; +} + +static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ + + info->time_defined = 1; + info->time.year = 256u * data[0] + data[1]; + info->time.month = data[2]; + info->time.day = data[3]; + info->time.hour = data[4]; + info->time.minute = data[5]; + info->time.second = data[6]; + + return 0; /* OK */ +} + +static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ + + info->phys_defined = 1; + info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; + info->phys_unit = data[8]; + + return 0; /* OK */ +} + +static unsigned readChunk_gAMA(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/ + + info->gama_defined = 1; + info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + + return 0; /* OK */ +} + +static unsigned readChunk_cHRM(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/ + + info->chrm_defined = 1; + info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3]; + info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7]; + info->chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11]; + info->chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15]; + info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19]; + info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23]; + info->chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27]; + info->chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31]; + + return 0; /* OK */ +} + +static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/ + + info->srgb_defined = 1; + info->srgb_intent = data[0]; + + return 0; /* OK */ +} + +static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, + const unsigned char* data, size_t chunkLength) { + unsigned error = 0; + unsigned i; + size_t size = 0; + /*copy the object to change parameters in it*/ + LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; + + unsigned length, string2_begin; + + if(info->iccp_defined) lodepng_clear_icc(info); + info->iccp_defined = 1; + + for(length = 0; length < chunkLength && data[length] != 0; ++length) ; + if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/ + if(length < 1 || length > 79) return 89; /*keyword too short or long*/ + + info->iccp_name = (char*)lodepng_malloc(length + 1); + if(!info->iccp_name) return 83; /*alloc fail*/ + + info->iccp_name[length] = 0; + for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i]; + + if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/ + + string2_begin = length + 2; + if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/ + + length = (unsigned)chunkLength - string2_begin; + zlibsettings.max_output_size = decoder->max_icc_size; + error = zlib_decompress(&info->iccp_profile, &size, 0, + &data[string2_begin], + length, &zlibsettings); + /*error: ICC profile larger than decoder->max_icc_size*/ + if(error && size > zlibsettings.max_output_size) error = 113; + info->iccp_profile_size = (unsigned)size; + if(!error && !info->iccp_profile_size) error = 100; /*invalid ICC profile size*/ + return error; +} + +static unsigned readChunk_cICP(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 4) return 117; /*invalid cICP chunk size*/ + + info->cicp_defined = 1; + /* No error checking for value ranges is done here, that is up to a CICP + handling library, not the PNG decoding. Just pass on the metadata. */ + info->cicp_color_primaries = data[0]; + info->cicp_transfer_function = data[1]; + info->cicp_matrix_coefficients = data[2]; + info->cicp_video_full_range_flag = data[3]; + + return 0; /* OK */ +} + +static unsigned readChunk_mDCV(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 24) return 119; /*invalid mDCV chunk size*/ + + info->mdcv_defined = 1; + info->mdcv_red_x = 256u * data[0] + data[1]; + info->mdcv_red_y = 256u * data[2] + data[3]; + info->mdcv_green_x = 256u * data[4] + data[5]; + info->mdcv_green_y = 256u * data[6] + data[7]; + info->mdcv_blue_x = 256u * data[8] + data[9]; + info->mdcv_blue_y = 256u * data[10] + data[11]; + info->mdcv_white_x = 256u * data[12] + data[13]; + info->mdcv_white_y = 256u * data[14] + data[15]; + info->mdcv_max_luminance = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19]; + info->mdcv_min_luminance = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23]; + + return 0; /* OK */ +} + +static unsigned readChunk_cLLI(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + if(chunkLength != 8) return 120; /*invalid cLLI chunk size*/ + + info->clli_defined = 1; + info->clli_max_cll = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + info->clli_max_fall = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; + + return 0; /* OK */ +} + +static unsigned readChunk_eXIf(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + return lodepng_set_exif(info, data, (unsigned)chunkLength); +} + +/*significant bits chunk (sBIT)*/ +static unsigned readChunk_sBIT(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { + unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth; + if(info->color.colortype == LCT_GREY) { + /*error: this chunk must be 1 bytes for grayscale image*/ + if(chunkLength != 1) return 114; + if(data[0] == 0 || data[0] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/ + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) { + /*error: this chunk must be 3 bytes for RGB and palette image*/ + if(chunkLength != 3) return 114; + if(data[0] == 0 || data[1] == 0 || data[2] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = data[0]; + info->sbit_g = data[1]; + info->sbit_b = data[2]; + } else if(info->color.colortype == LCT_GREY_ALPHA) { + /*error: this chunk must be 2 byte for grayscale with alpha image*/ + if(chunkLength != 2) return 114; + if(data[0] == 0 || data[1] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/ + info->sbit_a = data[1]; + } else if(info->color.colortype == LCT_RGBA) { + /*error: this chunk must be 4 bytes for grayscale image*/ + if(chunkLength != 4) return 114; + if(data[0] == 0 || data[1] == 0 || data[2] == 0 || data[3] == 0) return 115; + if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth || data[3] > bitdepth) return 115; + info->sbit_defined = 1; + info->sbit_r = data[0]; + info->sbit_g = data[1]; + info->sbit_b = data[2]; + info->sbit_a = data[3]; + } + + return 0; /* OK */ +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, + const unsigned char* in, size_t insize) { + const unsigned char* chunk = in + pos; + unsigned chunkLength; + const unsigned char* data; + unsigned unhandled = 0; + unsigned error = 0; + + if(pos + 4 > insize) return 30; + chunkLength = lodepng_chunk_length(chunk); + if(chunkLength > 2147483647) return 63; + data = lodepng_chunk_data_const(chunk); + if(chunkLength + 12 > insize - pos) return 30; + + if(lodepng_chunk_type_equals(chunk, "PLTE")) { + error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { + error = readChunk_tRNS(&state->info_png.color, data, chunkLength); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { + error = readChunk_bKGD(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { + error = readChunk_tEXt(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { + error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { + error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "tIME")) { + error = readChunk_tIME(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { + error = readChunk_pHYs(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { + error = readChunk_gAMA(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { + error = readChunk_cHRM(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { + error = readChunk_sRGB(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { + error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "cICP")) { + error = readChunk_cICP(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "mDCV")) { + error = readChunk_mDCV(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "cLLI")) { + error = readChunk_cLLI(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "eXIf")) { + error = readChunk_eXIf(&state->info_png, data, chunkLength); + } else if(lodepng_chunk_type_equals(chunk, "sBIT")) { + error = readChunk_sBIT(&state->info_png, data, chunkLength); +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else { + /* unhandled chunk is ok (is not an error) */ + unhandled = 1; + } + + if(!error && !unhandled && !state->decoder.ignore_crc) { + if(lodepng_chunk_check_crc(chunk)) return 57; /*invalid CRC*/ + } + + return error; +} + +/*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ +static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) { + unsigned char IEND = 0; + const unsigned char* chunk; /*points to beginning of next chunk*/ + unsigned char* idat; /*the data from idat chunks, zlib compressed*/ + size_t idatsize = 0; + unsigned char* scanlines = 0; + size_t scanlines_size = 0, expected_size = 0; + size_t outsize = 0; + + /*for unknown chunk order*/ + unsigned unknown = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + + + /* safe output values in case error happens */ + *out = 0; + *w = *h = 0; + + state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ + if(state->error) return; + + if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) { + CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/ + } + + /*the input filesize is a safe upper bound for the sum of idat chunks size*/ + idat = (unsigned char*)lodepng_malloc(insize); + if(!idat) CERROR_RETURN(state->error, 83); /*alloc fail*/ + + chunk = &in[33]; /*first byte of the first chunk after the header*/ + + /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. + IDAT data is put at the start of the in buffer*/ + while(!IEND && !state->error) { + unsigned chunkLength; + const unsigned char* data; /*the data in the chunk*/ + size_t pos = (size_t)(chunk - in); + + /*error: next chunk out of bounds of the in buffer*/ + if(chunk < in || pos + 12 > insize) { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 30); + } + + /*length of the data of the chunk, excluding the 12 bytes for length, chunk type and CRC*/ + chunkLength = lodepng_chunk_length(chunk); + /*error: chunk length larger than the max PNG chunk size*/ + if(chunkLength > 2147483647) { + if(state->decoder.ignore_end) break; /*other errors may still happen though*/ + CERROR_BREAK(state->error, 63); + } + + if(pos + (size_t)chunkLength + 12 > insize || pos + (size_t)chunkLength + 12 < pos) { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk (or int overflow)*/ + } + + data = lodepng_chunk_data_const(chunk); + + unknown = 0; + + /*IDAT chunk, containing compressed image data*/ + if(lodepng_chunk_type_equals(chunk, "IDAT")) { + size_t newsize; + if(lodepng_addofl(idatsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95); + if(newsize > insize) CERROR_BREAK(state->error, 95); + lodepng_memcpy(idat + idatsize, data, chunkLength); + idatsize += chunkLength; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 3; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else if(lodepng_chunk_type_equals(chunk, "IEND")) { + /*IEND chunk*/ + IEND = 1; + } else if(lodepng_chunk_type_equals(chunk, "PLTE")) { + /*palette chunk (PLTE)*/ + state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + critical_pos = 2; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { + /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled + in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that + affects the alpha channel of pixels. */ + state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); + if(state->error) break; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*background color chunk (bKGD)*/ + } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { + state->error = readChunk_bKGD(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { + /*text chunk (tEXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_tEXt(&state->info_png, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { + /*compressed text chunk (zTXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { + /*international text chunk (iTXt)*/ + if(state->decoder.read_text_chunks) { + state->error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength); + if(state->error) break; + } + } else if(lodepng_chunk_type_equals(chunk, "tIME")) { + state->error = readChunk_tIME(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { + state->error = readChunk_pHYs(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { + state->error = readChunk_gAMA(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { + state->error = readChunk_cHRM(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { + state->error = readChunk_sRGB(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { + state->error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "cICP")) { + state->error = readChunk_cICP(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "mDCV")) { + state->error = readChunk_mDCV(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "cLLI")) { + state->error = readChunk_cLLI(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "eXIf")) { + state->error = readChunk_eXIf(&state->info_png, data, chunkLength); + if(state->error) break; + } else if(lodepng_chunk_type_equals(chunk, "sBIT")) { + state->error = readChunk_sBIT(&state->info_png, data, chunkLength); + if(state->error) break; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { + if(!lodepng_chunk_type_name_valid(chunk)) { + CERROR_BREAK(state->error, 121); /* invalid chunk type name */ + } + if(lodepng_chunk_reserved(chunk)) { + CERROR_BREAK(state->error, 122); /* invalid third lowercase character */ + } + + /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ + if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) { + CERROR_BREAK(state->error, 69); + } + + unknown = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(state->decoder.remember_unknown_chunks) { + state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], + &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); + if(state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + } + + if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ { + if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ + } + + if(!IEND) chunk = lodepng_chunk_next_const(chunk, in + insize); + } + + if(!state->error && state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) { + state->error = 106; /* error: PNG file must have PLTE chunk if color type is palette */ + } + + if(!state->error) { + /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. + If the decompressed size does not match the prediction, the image must be corrupt.*/ + if(state->info_png.interlace_method == 0) { + unsigned bpp = lodepng_get_bpp(&state->info_png.color); + expected_size = lodepng_get_raw_size_idat(*w, *h, bpp); + } else { + unsigned bpp = lodepng_get_bpp(&state->info_png.color); + /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/ + expected_size = 0; + expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp); + if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, bpp); + if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, bpp); + if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, bpp); + expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, bpp); + } + + state->error = zlib_decompress(&scanlines, &scanlines_size, expected_size, idat, idatsize, &state->decoder.zlibsettings); + } + if(!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/ + lodepng_free(idat); + + if(!state->error) { + outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!*out) state->error = 83; /*alloc fail*/ + } + if(!state->error) { + lodepng_memset(*out, 0, outsize); + state->error = postProcessScanlines(*out, scanlines, *w, *h, &state->info_png); + } + lodepng_free(scanlines); +} + +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize) { + *out = 0; + decodeGeneric(out, w, h, state, in, insize); + if(state->error) return state->error; + if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { + /*same color type, no copying or converting of data needed*/ + /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype + the raw image has to the end user*/ + if(!state->decoder.color_convert) { + state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); + if(state->error) return state->error; + } + } else { /*color conversion needed*/ + unsigned char* data = *out; + size_t outsize; + + /*TODO: check if this works according to the statement in the documentation: "The converter can convert + from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/ + if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) + && !(state->info_raw.bitdepth == 8)) { + return 56; /*unsupported color mode conversion*/ + } + + outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); + *out = (unsigned char*)lodepng_malloc(outsize); + if(!(*out)) { + state->error = 83; /*alloc fail*/ + } + else state->error = lodepng_convert(*out, data, &state->info_raw, + &state->info_png.color, *w, *h); + lodepng_free(data); + } + return state->error; +} + +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*disable reading things that this function doesn't output*/ + state.decoder.read_text_chunks = 0; + state.decoder.remember_unknown_chunks = 0; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + error = lodepng_decode(out, w, h, &state, in, insize); + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); +} + +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer = 0; + size_t buffersize; + unsigned error; + /* safe output values in case error happens */ + *out = 0; + *w = *h = 0; + error = lodepng_load_file(&buffer, &buffersize, filename); + if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { + return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); +} + +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { + return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) { + settings->color_convert = 1; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->read_text_chunks = 1; + settings->remember_unknown_chunks = 0; + settings->max_text_size = 16777216; + settings->max_icc_size = 16777216; /* 16MB is much more than enough for any reasonable ICC profile */ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + settings->ignore_crc = 0; + settings->ignore_critical = 0; + settings->ignore_end = 0; + lodepng_decompress_settings_init(&settings->zlibsettings); +} + +#endif /*LODEPNG_COMPILE_DECODER*/ + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) + +void lodepng_state_init(LodePNGState* state) { +#ifdef LODEPNG_COMPILE_DECODER + lodepng_decoder_settings_init(&state->decoder); +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + lodepng_encoder_settings_init(&state->encoder); +#endif /*LODEPNG_COMPILE_ENCODER*/ + lodepng_color_mode_init(&state->info_raw); + lodepng_info_init(&state->info_png); + state->error = 1; +} + +void lodepng_state_cleanup(LodePNGState* state) { + lodepng_color_mode_cleanup(&state->info_raw); + lodepng_info_cleanup(&state->info_png); +} + +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) { + lodepng_state_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->info_raw); + lodepng_info_init(&dest->info_png); + dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; + dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; +} + +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_ENCODER + +/* ////////////////////////////////////////////////////////////////////////// */ +/* / PNG Encoder / */ +/* ////////////////////////////////////////////////////////////////////////// */ + + +static unsigned writeSignature(ucvector* out) { + size_t pos = out->size; + const unsigned char signature[] = {137, 80, 78, 71, 13, 10, 26, 10}; + /*8 bytes PNG signature, aka the magic bytes*/ + if(!ucvector_resize(out, out->size + 8)) return 83; /*alloc fail*/ + lodepng_memcpy(out->data + pos, signature, 8); + return 0; +} + +static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) { + unsigned char *chunk, *data; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 13, "IHDR")); + data = chunk + 8; + + lodepng_set32bitInt(data + 0, w); /*width*/ + lodepng_set32bitInt(data + 4, h); /*height*/ + data[8] = (unsigned char)bitdepth; /*bit depth*/ + data[9] = (unsigned char)colortype; /*color type*/ + data[10] = 0; /*compression method*/ + data[11] = 0; /*filter method*/ + data[12] = interlace_method; /*interlace method*/ + + lodepng_chunk_generate_crc(chunk); + return 0; +} + +/* only adds the chunk if needed (there is a key or palette with alpha) */ +static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) { + unsigned char* chunk; + size_t i, j = 8; + + if(info->palettesize == 0 || info->palettesize > 256) { + return 68; /*invalid palette size, it is only allowed to be 1-256*/ + } + + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, info->palettesize * 3, "PLTE")); + + for(i = 0; i != info->palettesize; ++i) { + /*add all channels except alpha channel*/ + chunk[j++] = info->palette[i * 4 + 0]; + chunk[j++] = info->palette[i * 4 + 1]; + chunk[j++] = info->palette[i * 4 + 2]; + } + + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { + unsigned char* chunk = 0; + + if(info->colortype == LCT_PALETTE) { + size_t i, amount = info->palettesize; + /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ + for(i = info->palettesize; i != 0; --i) { + if(info->palette[4 * (i - 1) + 3] != 255) break; + --amount; + } + if(amount) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, amount, "tRNS")); + /*add the alpha channel values from the palette*/ + for(i = 0; i != amount; ++i) chunk[8 + i] = info->palette[4 * i + 3]; + } + } else if(info->colortype == LCT_GREY) { + if(info->key_defined) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "tRNS")); + chunk[8] = (unsigned char)(info->key_r >> 8); + chunk[9] = (unsigned char)(info->key_r & 255); + } + } else if(info->colortype == LCT_RGB) { + if(info->key_defined) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "tRNS")); + chunk[8] = (unsigned char)(info->key_r >> 8); + chunk[9] = (unsigned char)(info->key_r & 255); + chunk[10] = (unsigned char)(info->key_g >> 8); + chunk[11] = (unsigned char)(info->key_g & 255); + chunk[12] = (unsigned char)(info->key_b >> 8); + chunk[13] = (unsigned char)(info->key_b & 255); + } + } + + if(chunk) lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, + LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + unsigned char* zlib = 0; + size_t pos = 0; + size_t zlibsize = 0; + /* max chunk length allowed by the specification is 2147483647 bytes */ + const size_t max_chunk_length = 2147483647u; + + error = zlib_compress(&zlib, &zlibsize, data, datasize, zlibsettings); + while(!error) { + if(zlibsize - pos > max_chunk_length) { + error = lodepng_chunk_createv(out, max_chunk_length, "IDAT", zlib + pos); + pos += max_chunk_length; + } else { + error = lodepng_chunk_createv(out, zlibsize - pos, "IDAT", zlib + pos); + break; + } + } + lodepng_free(zlib); + return error; +} + +static unsigned addChunk_IEND(ucvector* out) { + return lodepng_chunk_createv(out, 0, "IEND", 0); +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + +static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) { + unsigned char* chunk = 0; + size_t keysize = lodepng_strlen(keyword), textsize = lodepng_strlen(textstring); + size_t size = keysize + 1 + textsize; + if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, size, "tEXt")); + lodepng_memcpy(chunk + 8, keyword, keysize); + chunk[8 + keysize] = 0; /*null termination char*/ + lodepng_memcpy(chunk + 9 + keysize, textstring, textsize); + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, + LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + unsigned char* chunk = 0; + unsigned char* compressed = 0; + size_t compressedsize = 0; + size_t textsize = lodepng_strlen(textstring); + size_t keysize = lodepng_strlen(keyword); + if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ + + error = zlib_compress(&compressed, &compressedsize, + (const unsigned char*)textstring, textsize, zlibsettings); + if(!error) { + size_t size = keysize + 2 + compressedsize; + error = lodepng_chunk_init(&chunk, out, size, "zTXt"); + } + if(!error) { + lodepng_memcpy(chunk + 8, keyword, keysize); + chunk[8 + keysize] = 0; /*null termination char*/ + chunk[9 + keysize] = 0; /*compression method: 0*/ + lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize); + lodepng_chunk_generate_crc(chunk); + } + + lodepng_free(compressed); + return error; +} + +static unsigned addChunk_iTXt(ucvector* out, unsigned compress, const char* keyword, const char* langtag, + const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + unsigned char* chunk = 0; + unsigned char* compressed = 0; + size_t compressedsize = 0; + size_t textsize = lodepng_strlen(textstring); + size_t keysize = lodepng_strlen(keyword), langsize = lodepng_strlen(langtag), transsize = lodepng_strlen(transkey); + + if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ + + if(compress) { + error = zlib_compress(&compressed, &compressedsize, + (const unsigned char*)textstring, textsize, zlibsettings); + } + if(!error) { + size_t size = keysize + 3 + langsize + 1 + transsize + 1 + (compress ? compressedsize : textsize); + error = lodepng_chunk_init(&chunk, out, size, "iTXt"); + } + if(!error) { + size_t pos = 8; + lodepng_memcpy(chunk + pos, keyword, keysize); + pos += keysize; + chunk[pos++] = 0; /*null termination char*/ + chunk[pos++] = (compress ? 1 : 0); /*compression flag*/ + chunk[pos++] = 0; /*compression method: 0*/ + lodepng_memcpy(chunk + pos, langtag, langsize); + pos += langsize; + chunk[pos++] = 0; /*null termination char*/ + lodepng_memcpy(chunk + pos, transkey, transsize); + pos += transsize; + chunk[pos++] = 0; /*null termination char*/ + if(compress) { + lodepng_memcpy(chunk + pos, compressed, compressedsize); + } else { + lodepng_memcpy(chunk + pos, textstring, textsize); + } + lodepng_chunk_generate_crc(chunk); + } + + lodepng_free(compressed); + return error; +} + +static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk = 0; + if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "bKGD")); + chunk[8] = (unsigned char)(info->background_r >> 8); + chunk[9] = (unsigned char)(info->background_r & 255); + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "bKGD")); + chunk[8] = (unsigned char)(info->background_r >> 8); + chunk[9] = (unsigned char)(info->background_r & 255); + chunk[10] = (unsigned char)(info->background_g >> 8); + chunk[11] = (unsigned char)(info->background_g & 255); + chunk[12] = (unsigned char)(info->background_b >> 8); + chunk[13] = (unsigned char)(info->background_b & 255); + } else if(info->color.colortype == LCT_PALETTE) { + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "bKGD")); + chunk[8] = (unsigned char)(info->background_r & 255); /*palette index*/ + } + if(chunk) lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 7, "tIME")); + chunk[8] = (unsigned char)(time->year >> 8); + chunk[9] = (unsigned char)(time->year & 255); + chunk[10] = (unsigned char)time->month; + chunk[11] = (unsigned char)time->day; + chunk[12] = (unsigned char)time->hour; + chunk[13] = (unsigned char)time->minute; + chunk[14] = (unsigned char)time->second; + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 9, "pHYs")); + lodepng_set32bitInt(chunk + 8, info->phys_x); + lodepng_set32bitInt(chunk + 12, info->phys_y); + chunk[16] = info->phys_unit; + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_gAMA(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "gAMA")); + lodepng_set32bitInt(chunk + 8, info->gama_gamma); + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_cHRM(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 32, "cHRM")); + lodepng_set32bitInt(chunk + 8, info->chrm_white_x); + lodepng_set32bitInt(chunk + 12, info->chrm_white_y); + lodepng_set32bitInt(chunk + 16, info->chrm_red_x); + lodepng_set32bitInt(chunk + 20, info->chrm_red_y); + lodepng_set32bitInt(chunk + 24, info->chrm_green_x); + lodepng_set32bitInt(chunk + 28, info->chrm_green_y); + lodepng_set32bitInt(chunk + 32, info->chrm_blue_x); + lodepng_set32bitInt(chunk + 36, info->chrm_blue_y); + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info) { + unsigned char data = info->srgb_intent; + return lodepng_chunk_createv(out, 1, "sRGB", &data); +} + +static unsigned addChunk_iCCP(ucvector* out, const LodePNGInfo* info, LodePNGCompressSettings* zlibsettings) { + unsigned error = 0; + unsigned char* chunk = 0; + unsigned char* compressed = 0; + size_t compressedsize = 0; + size_t keysize = lodepng_strlen(info->iccp_name); + + if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ + error = zlib_compress(&compressed, &compressedsize, + info->iccp_profile, info->iccp_profile_size, zlibsettings); + if(!error) { + size_t size = keysize + 2 + compressedsize; + error = lodepng_chunk_init(&chunk, out, size, "iCCP"); + } + if(!error) { + lodepng_memcpy(chunk + 8, info->iccp_name, keysize); + chunk[8 + keysize] = 0; /*null termination char*/ + chunk[9 + keysize] = 0; /*compression method: 0*/ + lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize); + lodepng_chunk_generate_crc(chunk); + } + + lodepng_free(compressed); + return error; +} + +static unsigned addChunk_cICP(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + /* Allow up to 255 since they are bytes. The ITU-R-BT.709 spec has a more + restricted set of valid values for each field, but that's up to the error + handling of a CICP library, not the PNG encoding/decoding, to manage. */ + if(info->cicp_color_primaries > 255) return 116; + if(info->cicp_transfer_function > 255) return 116; + if(info->cicp_matrix_coefficients > 255) return 116; + if(info->cicp_video_full_range_flag > 255) return 116; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "cICP")); + chunk[8 + 0] = (unsigned char)info->cicp_color_primaries; + chunk[8 + 1] = (unsigned char)info->cicp_transfer_function; + chunk[8 + 2] = (unsigned char)info->cicp_matrix_coefficients; + chunk[8 + 3] = (unsigned char)info->cicp_video_full_range_flag; + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_mDCV(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + /* Allow up to 65535 since they are 16-bit ints. */ + if(info->mdcv_red_x > 65535) return 118; + if(info->mdcv_red_y > 65535) return 118; + if(info->mdcv_green_x > 65535) return 118; + if(info->mdcv_green_y > 65535) return 118; + if(info->mdcv_blue_x > 65535) return 118; + if(info->mdcv_blue_y > 65535) return 118; + if(info->mdcv_white_x > 65535) return 118; + if(info->mdcv_white_y > 65535) return 118; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 24, "mDCV")); + chunk[8 + 0] = (unsigned char)((info->mdcv_red_x) >> 8u); + chunk[8 + 1] = (unsigned char)(info->mdcv_red_x); + chunk[8 + 2] = (unsigned char)((info->mdcv_red_y) >> 8u); + chunk[8 + 3] = (unsigned char)(info->mdcv_red_y); + chunk[8 + 4] = (unsigned char)((info->mdcv_green_x) >> 8u); + chunk[8 + 5] = (unsigned char)(info->mdcv_green_x); + chunk[8 + 6] = (unsigned char)((info->mdcv_green_y) >> 8u); + chunk[8 + 7] = (unsigned char)(info->mdcv_green_y); + chunk[8 + 8] = (unsigned char)((info->mdcv_blue_x) >> 8u); + chunk[8 + 9] = (unsigned char)(info->mdcv_blue_x); + chunk[8 + 10] = (unsigned char)((info->mdcv_blue_y) >> 8u); + chunk[8 + 11] = (unsigned char)(info->mdcv_blue_y); + chunk[8 + 12] = (unsigned char)((info->mdcv_white_x) >> 8u); + chunk[8 + 13] = (unsigned char)(info->mdcv_white_x); + chunk[8 + 14] = (unsigned char)((info->mdcv_white_y) >> 8u); + chunk[8 + 15] = (unsigned char)(info->mdcv_white_y); + lodepng_set32bitInt(chunk + 8 + 16, info->mdcv_max_luminance); + lodepng_set32bitInt(chunk + 8 + 20, info->mdcv_min_luminance); + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_cLLI(ucvector* out, const LodePNGInfo* info) { + unsigned char* chunk; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 8, "cLLI")); + lodepng_set32bitInt(chunk + 8 + 0, info->clli_max_cll); + lodepng_set32bitInt(chunk + 8 + 4, info->clli_max_fall); + lodepng_chunk_generate_crc(chunk); + return 0; +} + +static unsigned addChunk_eXIf(ucvector* out, const LodePNGInfo* info) { + return lodepng_chunk_createv(out, info->exif_size, "eXIf", info->exif); +} + +static unsigned addChunk_sBIT(ucvector* out, const LodePNGInfo* info) { + unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth; + unsigned char* chunk = 0; + if(info->color.colortype == LCT_GREY) { + if(info->sbit_r == 0 || info->sbit_r > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "sBIT")); + chunk[8] = info->sbit_r; + } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) { + if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0) return 115; + if(info->sbit_r > bitdepth || info->sbit_g > bitdepth || info->sbit_b > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 3, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_g; + chunk[10] = info->sbit_b; + } else if(info->color.colortype == LCT_GREY_ALPHA) { + if(info->sbit_r == 0 || info->sbit_a == 0) return 115; + if(info->sbit_r > bitdepth || info->sbit_a > bitdepth) return 115; + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_a; + } else if(info->color.colortype == LCT_RGBA) { + if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0 || info->sbit_a == 0 || + info->sbit_r > bitdepth || info->sbit_g > bitdepth || + info->sbit_b > bitdepth || info->sbit_a > bitdepth) { + return 115; + } + CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "sBIT")); + chunk[8] = info->sbit_r; + chunk[9] = info->sbit_g; + chunk[10] = info->sbit_b; + chunk[11] = info->sbit_a; + } + if(chunk) lodepng_chunk_generate_crc(chunk); + return 0; +} + +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, + size_t length, size_t bytewidth, unsigned char filterType) { + size_t i; + switch(filterType) { + case 0: /*None*/ + for(i = 0; i != length; ++i) out[i] = scanline[i]; + break; + case 1: /*Sub*/ + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; + break; + case 2: /*Up*/ + if(prevline) { + for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; + } else { + for(i = 0; i != length; ++i) out[i] = scanline[i]; + } + break; + case 3: /*Average*/ + if(prevline) { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); + } else { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); + } + break; + case 4: /*Paeth*/ + if(prevline) { + /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ + for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); + for(i = bytewidth; i < length; ++i) { + out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); + } + } else { + for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; + /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ + for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); + } + break; + default: return; /*invalid filter type given*/ + } +} + +/* integer binary logarithm, max return value is 31 */ +static size_t ilog2(size_t i) { + size_t result = 0; + if(i >= 65536) { result += 16; i >>= 16; } + if(i >= 256) { result += 8; i >>= 8; } + if(i >= 16) { result += 4; i >>= 4; } + if(i >= 4) { result += 2; i >>= 2; } + if(i >= 2) { result += 1; /*i >>= 1;*/ } + return result; +} + +/* integer approximation for i * log2(i), helper function for LFS_ENTROPY */ +static size_t ilog2i(size_t i) { + size_t l; + if(i == 0) return 0; + l = ilog2(i); + /* approximate i*log2(i): l is integer logarithm, ((i - (1u << l)) << 1u) + linearly approximates the missing fractional part multiplied by i */ + return i * l + ((i - (((size_t)1) << l)) << 1u); +} + +static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* color, const LodePNGEncoderSettings* settings) { + /* + For PNG filter method 0 + out must be a buffer with as size: h + (w * h * bpp + 7u) / 8u, because there are + the scanlines with 1 extra byte per scanline + */ + + unsigned bpp = lodepng_get_bpp(color); + /*the width of a scanline in bytes, not including the filter type*/ + size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u; + + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7u) / 8u; + const unsigned char* prevline = 0; + unsigned x, y; + unsigned error = 0; + LodePNGFilterStrategy strategy = settings->filter_strategy; + + if(settings->filter_palette_zero && (color->colortype == LCT_PALETTE || color->bitdepth < 8)) { + /*if the filter_palette_zero setting is enabled, override the filter strategy with + zero for all scanlines for palette and less-than-8-bitdepth images*/ + strategy = LFS_ZERO; + } + + if(bpp == 0) return 31; /*error: invalid color type*/ + + if(strategy >= LFS_ZERO && strategy <= LFS_FOUR) { + unsigned char type = (unsigned char)strategy; + for(y = 0; y != h; ++y) { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } else if(strategy == LFS_MINSUM) { + /*adaptive filtering: independently for each row, try all five filter types and select the one that produces the + smallest sum of absolute values per row.*/ + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned char type, bestType = 0; + + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) error = 83; /*alloc fail*/ + } + + if(!error) { + for(y = 0; y != h; ++y) { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) { + size_t sum = 0; + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + + /*calculate the sum of the result*/ + if(type == 0) { + for(x = 0; x != linebytes; ++x) sum += (unsigned char)(attempt[type][x]); + } else { + for(x = 0; x != linebytes; ++x) { + /*For differences, each byte should be treated as signed, values above 127 are negative + (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. + This means filtertype 0 is almost never chosen, but that is justified.*/ + unsigned char s = attempt[type][x]; + sum += s < 128 ? s : (255U - s); + } + } + + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum < smallest) { + bestType = type; + smallest = sum; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } else if(strategy == LFS_ENTROPY) { + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t bestSum = 0; + unsigned type, bestType = 0; + unsigned count[256]; + + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) error = 83; /*alloc fail*/ + } + + if(!error) { + for(y = 0; y != h; ++y) { + /*try the 5 filter types*/ + for(type = 0; type != 5; ++type) { + size_t sum = 0; + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + lodepng_memset(count, 0, 256 * sizeof(*count)); + for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; + ++count[type]; /*the filter type itself is part of the scanline*/ + for(x = 0; x != 256; ++x) { + sum += ilog2i(count[x]); + } + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || sum > bestSum) { + bestType = type; + bestSum = sum; + } + } + + prevline = &in[y * linebytes]; + + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + } + + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } else if(strategy == LFS_PREDEFINED) { + for(y = 0; y != h; ++y) { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + unsigned char type = settings->predefined_filters[y]; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } else if(strategy == LFS_BRUTE_FORCE) { + /*brute force filter chooser. + deflate the scanline after every filter attempt to see which one deflates best. + This is very slow and gives only slightly smaller, sometimes even larger, result*/ + size_t size[5]; + unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned type = 0, bestType = 0; + unsigned char* dummy; + LodePNGCompressSettings zlibsettings; + lodepng_memcpy(&zlibsettings, &settings->zlibsettings, sizeof(LodePNGCompressSettings)); + /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, + to simulate the true case where the tree is the same for the whole image. Sometimes it gives + better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare + cases better compression. It does make this a bit less slow, so it's worth doing this.*/ + zlibsettings.btype = 1; + /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG + images only, so disable it*/ + zlibsettings.custom_zlib = 0; + zlibsettings.custom_deflate = 0; + for(type = 0; type != 5; ++type) { + attempt[type] = (unsigned char*)lodepng_malloc(linebytes); + if(!attempt[type]) error = 83; /*alloc fail*/ + } + if(!error) { + for(y = 0; y != h; ++y) /*try the 5 filter types*/ { + for(type = 0; type != 5; ++type) { + unsigned testsize = (unsigned)linebytes; + /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ + + filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); + size[type] = 0; + dummy = 0; + zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); + lodepng_free(dummy); + /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ + if(type == 0 || size[type] < smallest) { + bestType = type; + smallest = size[type]; + } + } + prevline = &in[y * linebytes]; + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; + } + } + for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); + } + else return 88; /* unknown filter strategy */ + + return error; +} + +static void addPaddingBits(unsigned char* out, const unsigned char* in, + size_t olinebits, size_t ilinebits, unsigned h) { + /*The opposite of the removePaddingBits function + olinebits must be >= ilinebits*/ + unsigned y; + size_t diff = olinebits - ilinebits; + size_t obp = 0, ibp = 0; /*bit pointers*/ + for(y = 0; y != h; ++y) { + size_t x; + for(x = 0; x < ilinebits; ++x) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + /*obp += diff; --> no, fill in some value in the padding bits too, to avoid + "Use of uninitialised value of size ###" warning from valgrind*/ + for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); + } +} + +/* +in: non-interlaced image with size w*h +out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with + no padding bits between scanlines, but between reduced images so that each + reduced image starts at a byte. +bpp: bits per pixel +there are no padding bits, not between scanlines, not between reduced images +in has the following size in bits: w * h * bpp. +out is possibly bigger due to padding bits between reduced images +NOTE: comments about padding bits are only relevant if bpp < 8 +*/ +static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + + if(bpp >= 8) { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + size_t bytewidth = bpp / 8u; + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; + for(b = 0; b < bytewidth; ++b) { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { + for(i = 0; i != 7; ++i) { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for(y = 0; y < passh[i]; ++y) + for(x = 0; x < passw[i]; ++x) { + ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + for(b = 0; b < bpp; ++b) { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } +} + +/*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. +return value is error**/ +static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, + unsigned w, unsigned h, + const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) { + /* + This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: + *) if no Adam7: 1) add padding bits (= possible extra bits per scanline if bpp < 8) 2) filter + *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter + */ + size_t bpp = lodepng_get_bpp(&info_png->color); + unsigned error = 0; + if(info_png->interlace_method == 0) { + /*image size plus an extra byte per scanline + possible padding bits*/ + *outsize = (size_t)h + ((size_t)h * (((size_t)w * bpp + 7u) / 8u)); + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ + + if(!error) { + /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ + if(bpp < 8 && (size_t)w * bpp != (((size_t)w * bpp + 7u) / 8u) * 8u) { + unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7u) / 8u)); + if(!padded) error = 83; /*alloc fail*/ + if(!error) { + addPaddingBits(padded, in, (((size_t)w * bpp + 7u) / 8u) * 8u, (size_t)w * bpp, h); + error = filter(*out, padded, w, h, &info_png->color, settings); + } + lodepng_free(padded); + } else { + /*we can immediately filter into the out buffer, no other steps needed*/ + error = filter(*out, in, w, h, &info_png->color, settings); + } + } + } else /*interlace_method is 1 (Adam7)*/ { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned char* adam7; + + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, (unsigned)bpp); + + *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if(!(*out)) error = 83; /*alloc fail*/ + + adam7 = (unsigned char*)lodepng_malloc(passstart[7]); + if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ + + if(!error) { + unsigned i; + + Adam7_interlace(adam7, in, w, h, (unsigned)bpp); + for(i = 0; i != 7; ++i) { + if(bpp < 8) { + unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); + if(!padded) ERROR_BREAK(83); /*alloc fail*/ + addPaddingBits(padded, &adam7[passstart[i]], + (((size_t)passw[i] * bpp + 7u) / 8u) * 8u, (size_t)passw[i] * bpp, passh[i]); + error = filter(&(*out)[filter_passstart[i]], padded, + passw[i], passh[i], &info_png->color, settings); + lodepng_free(padded); + } else { + error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], + passw[i], passh[i], &info_png->color, settings); + } + + if(error) break; + } + } + + lodepng_free(adam7); + } + + return error; +} + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) { + unsigned char* inchunk = data; + while((size_t)(inchunk - data) < datasize) { + CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); + out->allocsize = out->size; /*fix the allocsize again*/ + inchunk = lodepng_chunk_next(inchunk, data + datasize); + } + return 0; +} + +static unsigned isGrayICCProfile(const unsigned char* profile, unsigned size) { + /* + It is a gray profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19 + are "RGB ". We do not perform any full parsing of the ICC profile here, other + than check those 4 bytes to grayscale profile. Other than that, validity of + the profile is not checked. This is needed only because the PNG specification + requires using a non-gray color model if there is an ICC profile with "RGB " + (sadly limiting compression opportunities if the input data is grayscale RGB + data), and requires using a gray color model if it is "GRAY". + */ + if(size < 20) return 0; + return profile[16] == 'G' && profile[17] == 'R' && profile[18] == 'A' && profile[19] == 'Y'; +} + +static unsigned isRGBICCProfile(const unsigned char* profile, unsigned size) { + /* See comment in isGrayICCProfile*/ + if(size < 20) return 0; + return profile[16] == 'R' && profile[17] == 'G' && profile[18] == 'B' && profile[19] == ' '; +} +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state) { + unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ + size_t datasize = 0; + ucvector outv = ucvector_init(NULL, 0); + LodePNGInfo info; + const LodePNGInfo* info_png = &state->info_png; + LodePNGColorMode auto_color; + + lodepng_info_init(&info); + lodepng_color_mode_init(&auto_color); + + /*provide some proper output values if error will happen*/ + *out = 0; + *outsize = 0; + state->error = 0; + + /*check input values validity*/ + if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette) + && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) { + /*this error is returned even if auto_convert is enabled and thus encoder could + generate the palette by itself: while allowing this could be possible in theory, + it may complicate the code or edge cases, and always requiring to give a palette + when setting this color type is a simpler contract*/ + state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ + goto cleanup; + } + if(state->encoder.zlibsettings.btype > 2) { + state->error = 61; /*error: invalid btype*/ + goto cleanup; + } + if(info_png->interlace_method > 1) { + state->error = 71; /*error: invalid interlace mode*/ + goto cleanup; + } + state->error = checkColorValidity(info_png->color.colortype, info_png->color.bitdepth); + if(state->error) goto cleanup; /*error: invalid color type given*/ + state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); + if(state->error) goto cleanup; /*error: invalid color type given*/ + + /* color convert and compute scanline filter types */ + lodepng_info_copy(&info, &state->info_png); + if(state->encoder.auto_convert) { + LodePNGColorStats stats; + unsigned allow_convert = 1; + lodepng_color_stats_init(&stats); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->iccp_defined && + isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { + /*the PNG specification does not allow to use palette with a GRAY ICC profile, even + if the palette has only gray colors, so disallow it.*/ + stats.allow_palette = 0; + } + if(info_png->iccp_defined && + isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { + /*the PNG specification does not allow to use grayscale color with RGB ICC profile, so disallow gray.*/ + stats.allow_greyscale = 0; + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + state->error = lodepng_compute_color_stats(&stats, image, w, h, &state->info_raw); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->background_defined) { + /*the background chunk's color must be taken into account as well*/ + unsigned r = 0, g = 0, b = 0; + LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16); + lodepng_convert_rgb(&r, &g, &b, + info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color); + state->error = lodepng_color_stats_add(&stats, r, g, b, 65535); + if(state->error) goto cleanup; + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + state->error = auto_choose_color(&auto_color, &state->info_raw, &stats); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->sbit_defined) { + /*if sbit is defined, due to strict requirements of which sbit values can be present for which color modes, + auto_convert can't be done in many cases. However, do support a few cases here. + TODO: more conversions may be possible, and it may also be possible to get a more appropriate color type out of + auto_choose_color if knowledge about sbit is used beforehand + */ + unsigned sbit_max = LODEPNG_MAX(LODEPNG_MAX(LODEPNG_MAX(info_png->sbit_r, info_png->sbit_g), + info_png->sbit_b), info_png->sbit_a); + unsigned equal = (!info_png->sbit_g || info_png->sbit_g == info_png->sbit_r) + && (!info_png->sbit_b || info_png->sbit_b == info_png->sbit_r) + && (!info_png->sbit_a || info_png->sbit_a == info_png->sbit_r); + allow_convert = 0; + if(info.color.colortype == LCT_PALETTE && + auto_color.colortype == LCT_PALETTE) { + /* input and output are palette, and in this case it may happen that palette data is + expected to be copied from info_raw into the info_png */ + allow_convert = 1; + } + /*going from 8-bit RGB to palette (or 16-bit as long as sbit_max <= 8) is possible + since both are 8-bit RGB for sBIT's purposes*/ + if(info.color.colortype == LCT_RGB && + auto_color.colortype == LCT_PALETTE && sbit_max <= 8) { + allow_convert = 1; + } + /*going from 8-bit RGBA to palette is also ok but only if sbit_a is exactly 8*/ + if(info.color.colortype == LCT_RGBA && auto_color.colortype == LCT_PALETTE && + info_png->sbit_a == 8 && sbit_max <= 8) { + allow_convert = 1; + } + /*going from 16-bit RGB(A) to 8-bit RGB(A) is ok if all sbit values are <= 8*/ + if((info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA) && info.color.bitdepth == 16 && + auto_color.colortype == info.color.colortype && auto_color.bitdepth == 8 && + sbit_max <= 8) { + allow_convert = 1; + } + /*going to less channels is ok if all bit values are equal (all possible values in sbit, + as well as the chosen bitdepth of the result). Due to how auto_convert works, + we already know that auto_color.colortype has less than or equal amount of channels than + info.colortype. Palette is not used here. This conversion is not allowed if + info_png->sbit_r < auto_color.bitdepth, because specifically for alpha, non-presence of + an sbit value heavily implies that alpha's bit depth is equal to the PNG bit depth (rather + than the bit depths set in the r, g and b sbit values, by how the PNG specification describes + handling tRNS chunk case with sBIT), so be conservative here about ignoring user input.*/ + if(info.color.colortype != LCT_PALETTE && auto_color.colortype != LCT_PALETTE && + equal && info_png->sbit_r == auto_color.bitdepth) { + allow_convert = 1; + } + } +#endif + if(state->encoder.force_palette) { + if(info.color.colortype != LCT_GREY && info.color.colortype != LCT_GREY_ALPHA && + (auto_color.colortype == LCT_GREY || auto_color.colortype == LCT_GREY_ALPHA)) { + /*user speficially forced a PLTE palette, so cannot convert to grayscale types because + the PNG specification only allows writing a suggested palette in PLTE for truecolor types*/ + allow_convert = 0; + } + } + if(allow_convert) { + lodepng_color_mode_copy(&info.color, &auto_color); +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*also convert the background chunk*/ + if(info_png->background_defined) { + if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b, + info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) { + state->error = 104; + goto cleanup; + } + } +#endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ + } + } +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + if(info_png->iccp_defined) { + unsigned gray_icc = isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); + unsigned rgb_icc = isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); + unsigned gray_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA; + if(!gray_icc && !rgb_icc) { + state->error = 100; /* Disallowed profile color type for PNG */ + goto cleanup; + } + if(gray_icc != gray_png) { + /*Not allowed to use RGB/RGBA/palette with GRAY ICC profile or vice versa, + or in case of auto_convert, it wasn't possible to find appropriate model*/ + state->error = state->encoder.auto_convert ? 102 : 101; + goto cleanup; + } + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) { + unsigned char* converted; + size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7u) / 8u; + + converted = (unsigned char*)lodepng_malloc(size); + if(!converted && size) state->error = 83; /*alloc fail*/ + if(!state->error) { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if(!state->error) { + state->error = preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + } + lodepng_free(converted); + if(state->error) goto cleanup; + } else { + state->error = preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + if(state->error) goto cleanup; + } + + /* output all PNG chunks */ { +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + size_t i; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*write signature and chunks*/ + state->error = writeSignature(&outv); + if(state->error) goto cleanup; + /*IHDR*/ + state->error = addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*unknown chunks between IHDR and PLTE*/ + if(info.unknown_chunks_data[0]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); + if(state->error) goto cleanup; + } + /*color profile chunks must come before PLTE */ + if(info.cicp_defined) { + state->error = addChunk_cICP(&outv, &info); + if(state->error) goto cleanup; + } + if(info.mdcv_defined) { + state->error = addChunk_mDCV(&outv, &info); + if(state->error) goto cleanup; + } + if(info.clli_defined) { + state->error = addChunk_cLLI(&outv, &info); + if(state->error) goto cleanup; + } + if(info.iccp_defined) { + state->error = addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings); + if(state->error) goto cleanup; + } + if(info.srgb_defined) { + state->error = addChunk_sRGB(&outv, &info); + if(state->error) goto cleanup; + } + if(info.gama_defined) { + state->error = addChunk_gAMA(&outv, &info); + if(state->error) goto cleanup; + } + if(info.chrm_defined) { + state->error = addChunk_cHRM(&outv, &info); + if(state->error) goto cleanup; + } + if(info_png->sbit_defined) { + state->error = addChunk_sBIT(&outv, &info); + if(state->error) goto cleanup; + } + if(info.exif_defined) { + state->error = addChunk_eXIf(&outv, &info); + if(state->error) goto cleanup; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*PLTE*/ + if(info.color.colortype == LCT_PALETTE) { + state->error = addChunk_PLTE(&outv, &info.color); + if(state->error) goto cleanup; + } + if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) { + /*force_palette means: write suggested palette for truecolor in PLTE chunk*/ + state->error = addChunk_PLTE(&outv, &info.color); + if(state->error) goto cleanup; + } + /*tRNS (this will only add if when necessary) */ + state->error = addChunk_tRNS(&outv, &info.color); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*bKGD (must come between PLTE and the IDAt chunks*/ + if(info.background_defined) { + state->error = addChunk_bKGD(&outv, &info); + if(state->error) goto cleanup; + } + /*pHYs (must come before the IDAT chunks)*/ + if(info.phys_defined) { + state->error = addChunk_pHYs(&outv, &info); + if(state->error) goto cleanup; + } + + /*unknown chunks between PLTE and IDAT*/ + if(info.unknown_chunks_data[1]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); + if(state->error) goto cleanup; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + /*IDAT (multiple IDAT chunks must be consecutive)*/ + state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); + if(state->error) goto cleanup; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*tIME*/ + if(info.time_defined) { + state->error = addChunk_tIME(&outv, &info.time); + if(state->error) goto cleanup; + } + /*tEXt and/or zTXt*/ + for(i = 0; i != info.text_num; ++i) { + if(lodepng_strlen(info.text_keys[i]) > 79) { + state->error = 66; /*text chunk too large*/ + goto cleanup; + } + if(lodepng_strlen(info.text_keys[i]) < 1) { + state->error = 67; /*text chunk too small*/ + goto cleanup; + } + if(state->encoder.text_compression) { + state->error = addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); + if(state->error) goto cleanup; + } else { + state->error = addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); + if(state->error) goto cleanup; + } + } + /*LodePNG version id in text chunk*/ + if(state->encoder.add_id) { + unsigned already_added_id_text = 0; + for(i = 0; i != info.text_num; ++i) { + const char* k = info.text_keys[i]; + /* Could use strcmp, but we're not calling or reimplementing this C library function for this use only */ + if(k[0] == 'L' && k[1] == 'o' && k[2] == 'd' && k[3] == 'e' && + k[4] == 'P' && k[5] == 'N' && k[6] == 'G' && k[7] == '\0') { + already_added_id_text = 1; + break; + } + } + if(already_added_id_text == 0) { + state->error = addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ + if(state->error) goto cleanup; + } + } + /*iTXt*/ + for(i = 0; i != info.itext_num; ++i) { + if(lodepng_strlen(info.itext_keys[i]) > 79) { + state->error = 66; /*text chunk too large*/ + goto cleanup; + } + if(lodepng_strlen(info.itext_keys[i]) < 1) { + state->error = 67; /*text chunk too small*/ + goto cleanup; + } + state->error = addChunk_iTXt( + &outv, state->encoder.text_compression, + info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], + &state->encoder.zlibsettings); + if(state->error) goto cleanup; + } + + /*unknown chunks between IDAT and IEND*/ + if(info.unknown_chunks_data[2]) { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); + if(state->error) goto cleanup; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + state->error = addChunk_IEND(&outv); + if(state->error) goto cleanup; + } + +cleanup: + lodepng_info_cleanup(&info); + lodepng_free(data); + lodepng_color_mode_cleanup(&auto_color); + + /*instead of cleaning the vector up, give it to the output*/ + *out = outv.data; + *outsize = outv.size; + + return state->error; +} + +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, + unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + state.info_png.color.colortype = colortype; + state.info_png.color.bitdepth = bitdepth; + lodepng_encode(out, outsize, image, w, h, &state); + error = state.error; + lodepng_state_cleanup(&state); + return error; +} + +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); + if(!error) error = lodepng_save_file(buffer, buffersize, filename); + lodepng_free(buffer); + return error; +} + +unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); +} + +unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { + return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); +} +#endif /*LODEPNG_COMPILE_DISK*/ + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) { + lodepng_compress_settings_init(&settings->zlibsettings); + settings->filter_palette_zero = 1; + settings->filter_strategy = LFS_MINSUM; + settings->auto_convert = 1; + settings->force_palette = 0; + settings->predefined_filters = 0; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + settings->add_id = 0; + settings->text_compression = 1; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/* +This returns the description of a numerical error code in English. This is also +the documentation of all the error codes. +*/ +const char* lodepng_error_text(unsigned code) { + switch(code) { + case 0: return "no error, everything went ok"; + case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ + case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ + case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ + case 13: return "problem while processing dynamic deflate block"; + case 14: return "problem while processing dynamic deflate block"; + case 15: return "problem while processing dynamic deflate block"; + /*this error could happen if there are only 0 or 1 symbols present in the huffman code:*/ + case 16: return "invalid code while processing dynamic deflate block"; + case 17: return "end of out buffer memory reached while inflating"; + case 18: return "invalid distance code while inflating"; + case 19: return "end of out buffer memory reached while inflating"; + case 20: return "invalid deflate block BTYPE encountered while decoding"; + case 21: return "NLEN is not ones complement of LEN in a deflate block"; + + /*end of out buffer memory reached while inflating: + This can happen if the inflated deflate data is longer than the amount of bytes required to fill up + all the pixels of the image, given the color depth and image dimensions. Something that doesn't + happen in a normal, well encoded, PNG image.*/ + case 22: return "end of out buffer memory reached while inflating"; + case 23: return "end of in buffer memory reached while inflating"; + case 24: return "invalid FCHECK in zlib header"; + case 25: return "invalid compression method in zlib header"; + case 26: return "FDICT encountered in zlib header while it's not used for PNG"; + case 27: return "PNG file is smaller than a PNG header"; + /*Checks the magic file header, the first 8 bytes of the PNG file*/ + case 28: return "incorrect PNG signature, it's no PNG or corrupted"; + case 29: return "first chunk is not the header chunk"; + case 30: return "chunk length too large, chunk broken off at end of file"; + case 31: return "illegal PNG color type or bpp"; + case 32: return "illegal PNG compression method"; + case 33: return "illegal PNG filter method"; + case 34: return "illegal PNG interlace method"; + case 35: return "chunk length of a chunk is too large or the chunk too small"; + case 36: return "illegal PNG filter type encountered"; + case 37: return "illegal bit depth for this color type given"; + case 38: return "the palette is too small or too big"; /*0, or more than 256 colors*/ + case 39: return "tRNS chunk before PLTE or has more entries than palette size"; + case 40: return "tRNS chunk has wrong size for grayscale image"; + case 41: return "tRNS chunk has wrong size for RGB image"; + case 42: return "tRNS chunk appeared while it was not allowed for this color type"; + case 43: return "bKGD chunk has wrong size for palette image"; + case 44: return "bKGD chunk has wrong size for grayscale image"; + case 45: return "bKGD chunk has wrong size for RGB image"; + case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; + case 49: return "jumped past memory while generating dynamic huffman tree"; + case 50: return "jumped past memory while generating dynamic huffman tree"; + case 51: return "jumped past memory while inflating huffman block"; + case 52: return "jumped past memory while inflating"; + case 53: return "size of zlib data too small"; + case 54: return "repeat symbol in tree while there was no value symbol yet"; + /*jumped past tree while generating huffman tree, this could be when the + tree will have more leaves than symbols after generating it out of the + given lengths. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ + case 55: return "jumped past tree while generating huffman tree"; + case 56: return "given output image colortype or bitdepth not supported for color conversion"; + case 57: return "invalid CRC encountered (checking CRC can be disabled)"; + case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; + case 59: return "requested color conversion not supported"; + case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; + case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; + /*LodePNG leaves the choice of RGB to grayscale conversion formula to the user.*/ + case 62: return "conversion from color to grayscale not supported"; + /*(2^31-1)*/ + case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; + /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ + case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; + case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; + case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; + case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; + case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; + case 71: return "invalid interlace mode given to encoder (must be 0 or 1)"; + case 72: return "while decoding, invalid compression method encountering in zTXt or iTXt chunk (it must be 0)"; + case 73: return "invalid tIME chunk size"; + case 74: return "invalid pHYs chunk size"; + /*length could be wrong, or data chopped off*/ + case 75: return "no null termination char found while decoding text chunk"; + case 76: return "iTXt chunk too short to contain required bytes"; + case 77: return "integer overflow in buffer size"; + case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ + case 79: return "failed to open file for writing"; + case 80: return "tried creating a tree of 0 symbols"; + case 81: return "lazy matching at pos 0 is impossible"; + case 82: return "color conversion to palette requested while a color isn't in palette, or index out of bounds"; + case 83: return "memory allocation failed"; + case 84: return "given image too small to contain all pixels to be encoded"; + case 86: return "impossible offset in lz77 encoding (internal bug)"; + case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; + case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; + case 89: return "text chunk keyword too short or long: must have size 1-79"; + /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ + case 90: return "windowsize must be a power of two"; + case 91: return "invalid decompressed idat size"; + case 92: return "integer overflow due to too many pixels"; + case 93: return "zero width or height is invalid"; + case 94: return "header chunk must have a size of 13 bytes"; + case 95: return "integer overflow with combined idat chunk size"; + case 96: return "invalid gAMA chunk size"; + case 97: return "invalid cHRM chunk size"; + case 98: return "invalid sRGB chunk size"; + case 99: return "invalid sRGB rendering intent"; + case 100: return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY"; + case 101: return "PNG specification does not allow RGB ICC profile on gray color types and vice versa"; + case 102: return "not allowed to set grayscale ICC profile with colored pixels by PNG specification"; + case 103: return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?"; + case 104: return "invalid bKGD color while encoding (e.g. palette index out of range)"; + case 105: return "integer overflow of bitsize"; + case 106: return "PNG file must have PLTE chunk if color type is palette"; + case 107: return "color convert from palette mode requested without setting the palette data in it"; + case 108: return "tried to add more than 256 values to a palette"; + /*this limit can be configured in LodePNGDecompressSettings*/ + case 109: return "tried to decompress zlib or deflate data larger than desired max_output_size"; + case 110: return "custom zlib or inflate decompression failed"; + case 111: return "custom zlib or deflate compression failed"; + /*max text size limit can be configured in LodePNGDecoderSettings. This error prevents + unreasonable memory consumption when decoding due to impossibly large text sizes.*/ + case 112: return "compressed text unreasonably large"; + /*max ICC size limit can be configured in LodePNGDecoderSettings. This error prevents + unreasonable memory consumption when decoding due to impossibly large ICC profile*/ + case 113: return "ICC profile unreasonably large"; + case 114: return "sBIT chunk has wrong size for the color type of the image"; + case 115: return "sBIT value out of range"; + case 116: return "cICP value out of range"; + case 117: return "invalid cICP chunk size"; + case 118: return "mDCV value out of range"; + case 119: return "invalid mDCV chunk size"; + case 120: return "invalid cLLI chunk size"; + case 121: return "invalid chunk type name: may only contain [a-zA-Z]"; + case 122: return "invalid chunk type name: third character must be uppercase"; + } + return "unknown error code"; +} +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* // C++ Wrapper // */ +/* ////////////////////////////////////////////////////////////////////////// */ +/* ////////////////////////////////////////////////////////////////////////// */ + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng { + +#ifdef LODEPNG_COMPILE_DISK +/* Resizes the vector to the file size and reads the file into it. Returns error code.*/ +static unsigned load_file_(std::vector& buffer, FILE* file) { + long size = lodepng_filesize(file); + if(size < 0) return 78; + buffer.resize((size_t)size); + if(size == 0) return 0; /*ok*/ + if(fread(&buffer[0], 1, buffer.size(), file) != buffer.size()) return 78; + return 0; /*ok*/ +} + +unsigned load_file(std::vector& buffer, const std::string& filename) { + unsigned error; + FILE* file = fopen(filename.c_str(), "rb"); + if(!file) return 78; + error = load_file_(buffer, file); + fclose(file); + return error; +} + +/*write given buffer to the file, overwriting the file, it doesn't append to it.*/ +unsigned save_file(const std::vector& buffer, const std::string& filename) { + return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); +} +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings) { + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_decompress(&buffer, &buffersize, 0, in, insize, &settings); + if(buffer) { + out.insert(out.end(), buffer, &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings) { + return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings) { + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); + if(buffer) { + out.insert(out.end(), buffer, &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings) { + return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); +} +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ + + +#ifdef LODEPNG_COMPILE_PNG + +State::State() { + lodepng_state_init(this); +} + +State::State(const State& other) { + lodepng_state_init(this); + lodepng_state_copy(this, &other); +} + +State::~State() { + lodepng_state_cleanup(this); +} + +State& State::operator=(const State& other) { + lodepng_state_copy(this, &other); + return *this; +} + +#ifdef LODEPNG_COMPILE_DECODER + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer = 0; + unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); + if(buffer && !error) { + State state; + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), buffer, &buffer[buffersize]); + } + lodepng_free(buffer); + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) { + return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize) { + unsigned char* buffer = NULL; + unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); + if(buffer && !error) { + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), buffer, &buffer[buffersize]); + } + lodepng_free(buffer); + return error; +} + +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in) { + return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, + LodePNGColorType colortype, unsigned bitdepth) { + std::vector buffer; + /* safe output values in case error happens */ + w = h = 0; + unsigned error = load_file(buffer, filename); + if(error) return error; + return decode(out, w, h, buffer, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DECODER */ +#endif /* LODEPNG_COMPILE_DISK */ + +#ifdef LODEPNG_COMPILE_ENCODER +unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); + if(buffer) { + out.insert(out.end(), buffer, &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} + +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state) { + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); + if(buffer) { + out.insert(out.end(), buffer, &buffer[buffersize]); + lodepng_free(buffer); + } + return error; +} + +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state) { + if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, state); +} + +#ifdef LODEPNG_COMPILE_DISK +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + std::vector buffer; + unsigned error = encode(buffer, in, w, h, colortype, bitdepth); + if(!error) error = save_file(buffer, filename); + return error; +} + +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { + if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); +} +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_PNG */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ diff --git a/lodepng.h b/lodepng.h new file mode 100644 index 0000000..c157021 --- /dev/null +++ b/lodepng.h @@ -0,0 +1,2173 @@ +/* +LodePNG version 20250506 + +Copyright (c) 2005-2025 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +#ifndef LODEPNG_H +#define LODEPNG_H + +#include /*for size_t*/ + +extern const char* LODEPNG_VERSION_STRING; + +/* +The following #defines are used to create code sections. They can be disabled +to disable code sections, which can give faster compile time and smaller binary. +The "NO_COMPILE" defines are designed to be used to pass as defines to the +compiler command to disable them without modifying this header, e.g. +-DLODEPNG_NO_COMPILE_ZLIB for gcc or clang. +*/ +/*deflate & zlib. If disabled, you must specify alternative zlib functions in +the custom_zlib field of the compress and decompress settings*/ +#ifndef LODEPNG_NO_COMPILE_ZLIB +/*pass -DLODEPNG_NO_COMPILE_ZLIB to the compiler to disable this, or comment out LODEPNG_COMPILE_ZLIB below*/ +#define LODEPNG_COMPILE_ZLIB +#endif + +/*png encoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_PNG +/*pass -DLODEPNG_NO_COMPILE_PNG to the compiler to disable this, or comment out LODEPNG_COMPILE_PNG below*/ +#define LODEPNG_COMPILE_PNG +#endif + +/*deflate&zlib decoder and png decoder*/ +#ifndef LODEPNG_NO_COMPILE_DECODER +/*pass -DLODEPNG_NO_COMPILE_DECODER to the compiler to disable this, or comment out LODEPNG_COMPILE_DECODER below*/ +#define LODEPNG_COMPILE_DECODER +#endif + +/*deflate&zlib encoder and png encoder*/ +#ifndef LODEPNG_NO_COMPILE_ENCODER +/*pass -DLODEPNG_NO_COMPILE_ENCODER to the compiler to disable this, or comment out LODEPNG_COMPILE_ENCODER below*/ +#define LODEPNG_COMPILE_ENCODER +#endif + +/*the optional built in harddisk file loading and saving functions*/ +#ifndef LODEPNG_NO_COMPILE_DISK +/*pass -DLODEPNG_NO_COMPILE_DISK to the compiler to disable this, or comment out LODEPNG_COMPILE_DISK below*/ +#define LODEPNG_COMPILE_DISK +#endif + +/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ +#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS +/*pass -DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS to the compiler to disable this, +or comment out LODEPNG_COMPILE_ANCILLARY_CHUNKS below*/ +#define LODEPNG_COMPILE_ANCILLARY_CHUNKS +#endif + +/*ability to convert error numerical codes to English text string*/ +#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT +/*pass -DLODEPNG_NO_COMPILE_ERROR_TEXT to the compiler to disable this, +or comment out LODEPNG_COMPILE_ERROR_TEXT below*/ +#define LODEPNG_COMPILE_ERROR_TEXT +#endif + +/*Compile the default allocators (C's free, malloc and realloc). If you disable this, +you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your +source files with custom allocators.*/ +#ifndef LODEPNG_NO_COMPILE_ALLOCATORS +/*pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler to disable the built-in ones, +or comment out LODEPNG_COMPILE_ALLOCATORS below*/ +#define LODEPNG_COMPILE_ALLOCATORS +#endif + +/*Disable built-in CRC function, in that case a custom implementation of +lodepng_crc32 must be defined externally so that it can be linked in. +The default built-in CRC code comes with 8KB of lookup tables, so for memory constrained environment you may want it +disabled and provide a much smaller implementation externally as said above. You can find such an example implementation +in a comment in the lodepng.c(pp) file in the 'else' case of the searchable LODEPNG_COMPILE_CRC section.*/ +#ifndef LODEPNG_NO_COMPILE_CRC +/*pass -DLODEPNG_NO_COMPILE_CRC to the compiler to disable the built-in one, +or comment out LODEPNG_COMPILE_CRC below*/ +#define LODEPNG_COMPILE_CRC +#endif + +/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ +#ifdef __cplusplus +#ifndef LODEPNG_NO_COMPILE_CPP +/*pass -DLODEPNG_NO_COMPILE_CPP to the compiler to disable C++ (not needed if a C-only compiler), +or comment out LODEPNG_COMPILE_CPP below*/ +#define LODEPNG_COMPILE_CPP +#endif +#endif + +#ifdef LODEPNG_COMPILE_CPP +#include +#include +#endif /*LODEPNG_COMPILE_CPP*/ + +#ifdef LODEPNG_COMPILE_PNG +/*The PNG color types (also used for raw image).*/ +typedef enum LodePNGColorType { + LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ + LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/ + /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid + byte value from 0 to 255 that could be present in an invalid PNG file header. Do + not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use + the valid color type names above, or numeric values like 1 or 7 when checking for + particular disallowed color type byte values, or cast to integer to print it.*/ + LCT_MAX_OCTET_VALUE = 255 +} LodePNGColorType; + +#ifdef LODEPNG_COMPILE_DECODER +/* +Converts PNG data in memory to raw pixel data. +out: Output parameter. Pointer to buffer that will contain the raw pixel data. + After decoding, its size is w * h * (bytes per pixel) bytes larger than + initially. Bytes per pixel depends on colortype and bitdepth. + Must be freed after usage with free(*out). + Note: for 16-bit per channel colors, uses big endian format like PNG does. +w: Output parameter. Pointer to width of pixel data. +h: Output parameter. Pointer to height of pixel data. +in: Memory buffer with the PNG file. +insize: size of the in buffer. +colortype: the desired color type for the raw output image. See explanation on PNG color types. +bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ +unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +/*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ +unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, + const unsigned char* in, size_t insize); + +#ifdef LODEPNG_COMPILE_DISK +/* +Load PNG from disk, from file with given name. +Same as the other decode functions, but instead takes a filename as input. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); + +/*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory.*/ +unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, + const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_DECODER*/ + + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Converts raw pixel data into a PNG image in memory. The colortype and bitdepth + of the output PNG image cannot be chosen, they are automatically determined + by the colortype, bitdepth and content of the input pixel data. + Note: for 16-bit per channel colors, needs big endian format like PNG does. +out: Output parameter. Pointer to buffer that will contain the PNG image data. + Must be freed after usage with free(*out). +outsize: Output parameter. Pointer to the size in bytes of the out buffer. +image: The raw pixel data to encode. The size of this buffer should be + w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. +w: width of the raw pixel data in pixels. +h: height of the raw pixel data in pixels. +colortype: the color type of the raw input image. See explanation on PNG color types. +bitdepth: the bit depth of the raw input image. See explanation on PNG color types. +Return value: LodePNG error code (0 means no error). +*/ +unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ +unsigned lodepng_encode32(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ +unsigned lodepng_encode24(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DISK +/* +Converts raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. + +NOTE: This overwrites existing files without warning! + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); + +/*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode32_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); + +/*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory.*/ +unsigned lodepng_encode24_file(const char* filename, + const unsigned char* image, unsigned w, unsigned h); +#endif /*LODEPNG_COMPILE_DISK*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#ifdef LODEPNG_COMPILE_CPP +namespace lodepng { +#ifdef LODEPNG_COMPILE_DECODER +/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype +is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const unsigned char* in, size_t insize, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::vector& in, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts PNG file from disk to raw pixel data in memory. +Same as the other decode functions, but instead takes a filename as input. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. +*/ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + const std::string& filename, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/*Same as lodepng_encode_memory, but encodes to an std::vector. colortype +is that of the raw input data. The output PNG color type will be auto chosen.*/ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#ifdef LODEPNG_COMPILE_DISK +/* +Converts 32-bit RGBA raw pixel data into a PNG file on disk. +Same as the other encode functions, but instead takes a filename as output. + +NOTE: This overwrites existing files without warning! + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. +*/ +unsigned encode(const std::string& filename, + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +unsigned encode(const std::string& filename, + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_ENCODER */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ +#endif /*LODEPNG_COMPILE_PNG*/ + +#ifdef LODEPNG_COMPILE_ERROR_TEXT +/*Returns an English description of the numerical error code.*/ +const char* lodepng_error_text(unsigned code); +#endif /*LODEPNG_COMPILE_ERROR_TEXT*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Settings for zlib decompression*/ +typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; +struct LodePNGDecompressSettings { + /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ + + /*Maximum decompressed size, beyond this the decoder may (and is encouraged to) stop decoding, + return an error, output a data size > max_output_size and all the data up to that point. This is + not hard limit nor a guarantee, but can prevent excessive memory usage. This setting is + ignored by the PNG decoder, but is used by the deflate/zlib decoder and can be used by custom ones. + Set to 0 to impose no limit (the default).*/ + size_t max_output_size; + + /*use custom zlib decoder instead of built in one (default: null). + Should return 0 if success, any non-0 if error (numeric value not exposed).*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + /*use custom deflate decoder instead of built in one (default: null) + if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate). + Should return 0 if success, any non-0 if error (numeric value not exposed).*/ + unsigned (*custom_inflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGDecompressSettings lodepng_default_decompress_settings; +void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Settings for zlib compression. Tweaking these settings tweaks the balance +between speed and compression ratio. +*/ +typedef struct LodePNGCompressSettings LodePNGCompressSettings; +struct LodePNGCompressSettings /*deflate = compress*/ { + /*LZ77 related settings*/ + unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ + unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ + unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ + unsigned minmatch; /*minimum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ + unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ + unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ + + /*use custom zlib encoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + /*use custom deflate encoder instead of built in one (default: null) + if custom_zlib is used, custom_deflate is ignored since only the built in + zlib function will call custom_deflate*/ + unsigned (*custom_deflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + + const void* custom_context; /*optional custom settings for custom functions*/ +}; + +extern const LodePNGCompressSettings lodepng_default_compress_settings; +void lodepng_compress_settings_init(LodePNGCompressSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_PNG +/* +Color mode of an image. Contains all information required to decode the pixel +bits to RGBA colors. This information is the same as used in the PNG file +format, and is used both for PNG and raw image data in LodePNG. +*/ +typedef struct LodePNGColorMode { + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + + /* + palette (PLTE and tRNS) + + Dynamically allocated with the colors of the palette, including alpha. + This field may not be allocated directly, use lodepng_color_mode_init first, + then lodepng_palette_add per color to correctly initialize it (to ensure size + of exactly 1024 bytes). + + The alpha channels must be set as well, set them to 255 for opaque images. + + When decoding, with the default settings you can ignore this palette, since + LodePNG already fills the palette colors in the pixels of the raw RGBA output, + but when decoding to the original PNG color mode it is needed to reconstruct + the colors. + + The palette is only supported for color type 3. + */ + unsigned char* palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/ + size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/ + + /* + transparent color key (tRNS) + + This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. + For grayscale PNGs, r, g and b will all 3 be set to the same. + + When decoding, by default you can ignore this information, since LodePNG sets + pixels with this key to transparent already in the raw RGBA output. + + The color key is only supported for color types 0 and 2. + */ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/grayscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ +} LodePNGColorMode; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_color_mode_init(LodePNGColorMode* info); +void lodepng_color_mode_cleanup(LodePNGColorMode* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); +/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */ +LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth); + +void lodepng_palette_clear(LodePNGColorMode* info); +/*add 1 color to the palette*/ +unsigned lodepng_palette_add(LodePNGColorMode* info, + unsigned char r, unsigned char g, unsigned char b, unsigned char a); + +/*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ +unsigned lodepng_get_bpp(const LodePNGColorMode* info); +/*get the amount of color channels used, based on colortype in the struct. +If a palette is used, it counts as 1 channel.*/ +unsigned lodepng_get_channels(const LodePNGColorMode* info); +/*is it a grayscale type? (only colortype 0 or 4)*/ +unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); +/*has it got an alpha channel? (only colortype 2 or 6)*/ +unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); +/*has it got a palette? (only colortype 3)*/ +unsigned lodepng_is_palette_type(const LodePNGColorMode* info); +/*only returns true if there is a palette and there is a value in the palette with alpha < 255. +Loops through the palette to check this.*/ +unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); +/* +Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. +Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). +Returns false if the image can only have opaque pixels. +In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, +or if "key_defined" is true. +*/ +unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); +/*Returns the byte size of a raw image buffer with given width, height and color mode*/ +size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +/*The information of a Time chunk in PNG.*/ +typedef struct LodePNGTime { + unsigned year; /*2 bytes used (0-65535)*/ + unsigned month; /*1-12*/ + unsigned day; /*1-31*/ + unsigned hour; /*0-23*/ + unsigned minute; /*0-59*/ + unsigned second; /*0-60 (to allow for leap seconds)*/ +} LodePNGTime; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/*Information about the PNG image, except pixels, width and height.*/ +typedef struct LodePNGInfo { + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method;/*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /* + Suggested background color chunk (bKGD) + + This uses the same color mode and bit depth as the PNG (except no alpha channel), + with values truncated to the bit depth in the unsigned integer. + + For grayscale and palette PNGs, the value is stored in background_r. The values + in background_g and background_b are then unused. The decoder will set them + equal to background_r, the encoder ignores them in this case. + + When decoding, you may get these in a different color mode than the one you requested + for the raw pixels: the colortype and bitdepth defined by info_png.color, that is the + ones defined in the header of the PNG image, are used. + + When encoding with auto_convert, you must use the color model defined in info_png.color for + these values. The encoder normally ignores info_png.color when auto_convert is on, but will + use it to interpret these values (and convert copies of them to its chosen color model). + + When encoding, avoid setting this to an expensive color, such as a non-gray value + when the image is gray, or the compression will be worse since it will be forced to + write the PNG with a more expensive color mode (when auto_convert is on). + + The decoder does not use this background color to edit the color of pixels. This is a + completely optional metadata feature. + */ + unsigned background_defined; /*is a suggested background color given?*/ + unsigned background_r; /*red/gray/palette component of suggested background color*/ + unsigned background_g; /*green component of suggested background color*/ + unsigned background_b; /*blue component of suggested background color*/ + + /* + Non-international text chunks (tEXt and zTXt) + + The char** arrays each contain num strings. The actual messages are in + text_strings, while text_keys are keywords that give a short description what + the actual text represents, e.g. Title, Author, Description, or anything else. + + All the string fields below including strings, keys, names and language tags are null terminated. + The PNG specification uses null characters for the keys, names and tags, and forbids null + characters to appear in the main text which is why we can use null termination everywhere here. + + A keyword is minimum 1 character and maximum 79 characters long (plus the + additional null terminator). It's discouraged to use a single line length + longer than 79 characters for texts. + + Don't allocate these text buffers yourself. Use the init/cleanup functions + correctly and use lodepng_add_text and lodepng_clear_text. + + Standard text chunk keywords and strings are encoded using Latin-1. + */ + size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ + char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ + char** text_strings; /*the actual text*/ + + /* + International text chunks (iTXt) + Similar to the non-international text chunks, but with additional strings + "langtags" and "transkeys", and the following text encodings are used: + keys: Latin-1, langtags: ASCII, transkeys and strings: UTF-8. + keys must be 1-79 characters (plus the additional null terminator), the other + strings are any length. + */ + size_t itext_num; /*the amount of international texts in this PNG*/ + char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ + char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ + char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ + char** itext_strings; /*the actual international text - UTF-8 string*/ + + /* + Optional exif metadata in exif_size bytes. + Don't allocate this buffer yourself. Use the init/cleanup functions + correctly and use lodepng_set_exif and lodepng_clear_exif. + The exif data is in exif-encoded form but without JPEG markers, starting with the 'II' or 'MM' marker that indicates + endianness. It's up to an exif handling library to encode/decode its information. + */ + unsigned exif_defined; /* Whether exif metadata is present, that is, the PNG image has an eXIf chunk */ + unsigned char* exif; /* The bytes of the exif metadata, if present */ + unsigned exif_size; /* The size of the exif data in bytes */ + + + /*time chunk (tIME)*/ + unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ + LodePNGTime time; + + /*phys chunk (pHYs)*/ + unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ + unsigned phys_x; /*pixels per unit in x direction*/ + unsigned phys_y; /*pixels per unit in y direction*/ + unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ + + /* + Color profile related chunk types: cICP, iCPP, sRGB, gAMA, cHRM, sBIT + + LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color + profile values. It merely passes on the information. If you wish to use color profiles and convert colors, a separate + color management library should be used. There is also a limited library for this in lodepng_util.h. + + There are 4 types of (sets of) chunks providing color information. If multiple are present, each will be decoded by + LodePNG, but only one should be handled by the user, with the following order of priority depending on what the user + supports: + 1: cICP: Coding-independent code points (CICP) + 2: iCCP: ICC profile + 3: sRGB: indicates the image is in the sRGB color profile + 4: gAMA and cHRM: indicates a gamma and chromaticity value to define the color profile + */ + + /* + gAMA chunk: Image gamma + Optional, overridden by cICP, iCCP or sRGB if those are present. + Together with cHRM, this is a primitive way of specifying the image color profile. + */ + unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */ + unsigned gama_gamma; /* Gamma exponent times 100000 */ + + /* + cHRM chunk: Primary chromaticities and white point + Optional, overridden by cICP, iCCP or sRGB if those are present. + Together with gAMA, this is a primitive way of specifying the image color profile. + */ + unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */ + unsigned chrm_white_x; /* White Point x times 100000 */ + unsigned chrm_white_y; /* White Point y times 100000 */ + unsigned chrm_red_x; /* Red x times 100000 */ + unsigned chrm_red_y; /* Red y times 100000 */ + unsigned chrm_green_x; /* Green x times 100000 */ + unsigned chrm_green_y; /* Green y times 100000 */ + unsigned chrm_blue_x; /* Blue x times 100000 */ + unsigned chrm_blue_y; /* Blue y times 100000 */ + + /* + sRGB chunk: Indicates the image is in the sRGB color space. + Optional. Should not appear at the same time as iCCP. + If gAMA is also present gAMA must contain value 45455. + If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000. + */ + unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */ + unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */ + + /* + iCCP chunk: Embedded ICC profile. + Optional. Should not appear at the same time as sRGB. + + Contains ICC profile, which can use any version of the ICC.1 specification by the International Color Consortium. See + its specification for more details. LodePNG does not parse or use the ICC profile (except its color space header + field for "RGB" or "GRAY", see below), a separate library to handle the ICC data format is needed to use it for color + management and conversions. + + For encoding, if iCCP is present, the PNG specification recommends to also add gAMA and cHRM chunks that approximate + the ICC profile, for compatibility with applications that don't use the ICC chunk. This is not required, and it's up + to the user to compute approximate values and set then in the appropriate gama_ and chrm_ fields, LodePNG does not do + this automatically since it does not interpret the ICC profile. + + For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray PNG color + types (types 2, 3 and 6) and a "GRAY" profile for gray PNG color types (types 1 and 4). If you disable auto_convert, + you must ensure the ICC profile type matches your requested color type, else the encoder gives an error. If + auto_convert is enabled (the default), and the ICC profile is not a correct match for the pixel data, this will result + in an encoder error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of + the pixel data if the pixels could be encoded as grayscale but the ICC profile is RGB. + + To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so + make sure you compute it carefully to avoid the above problems. + */ + unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */ + char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */ + /* + The ICC profile in iccp_profile_size bytes. + Don't allocate this buffer yourself. Use the init/cleanup functions + correctly and use lodepng_set_icc and lodepng_clear_icc. + */ + unsigned char* iccp_profile; + unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ + + /* + cICP chunk: Coding-independent code points for video signal type identification. + Optional. If present, and supported, overrides iCCP, sRGB, gAMA and cHRM. + The meaning of the values are as defined in the specification ITU-T-H.273. LodePNG does not + use these values, only passes on the metadata. The meaning of the values is they are enum + values representing certain color spaces, including HDR color spaces, such as Display P3, + PQ and HLG. The video full range flag value should typically be 1 for the use cases of PNG + images, but can be 0 for narrow-range images in certain video editing workflows. + */ + unsigned cicp_defined; /* Whether an cICP chunk is present (0 = not present, 1 = present). */ + unsigned cicp_color_primaries; /* Colour primaries value */ + unsigned cicp_transfer_function; /* Transfer characteristics value */ + unsigned cicp_matrix_coefficients; /* Matrix coefficients value */ + unsigned cicp_video_full_range_flag; /* Video full range flag value */ + + /* + mDCV chunk: Mastering Display Color Volume. + Optional, typically used in conjunction with certain HDR color spaces that can + be represented by the cICP chunk. + See the PNG specification, third edition, for more information on this chunk. + All the red, green, blue and white x and y values are encoded as 16-bit + integers and therefore must be in range 0-65536. The min and max luminance + values are 32-bit integers. + */ + unsigned mdcv_defined; /* Whether an mDCV chunk is present (0 = not present, 1 = present). */ + /* Mastering display color primary chromaticities (CIE 1931 x,y of R,G,B) */ + unsigned mdcv_red_x; /* Red x times 50000 */ + unsigned mdcv_red_y; /* Red y times 50000 */ + unsigned mdcv_green_x; /* Green x times 50000 */ + unsigned mdcv_green_y; /* Green y times 50000 */ + unsigned mdcv_blue_x; /* Blue x times 50000 */ + unsigned mdcv_blue_y; /* Blue y times 50000 */ + /* Mastering display white point chromaticity (CIE 1931 x,y) */ + unsigned mdcv_white_x; /* White Point x times 50000 */ + unsigned mdcv_white_y; /* White Point y times 50000 */ + /* Mastering display luminance */ + unsigned mdcv_max_luminance; /* Max luminance in cd/m^2 times 10000 */ + unsigned mdcv_min_luminance; /* Min luminance in cd/m^2 times 10000 */ + + /* + cLLI chunk: Content Light Level Information. + Optional, typically used in conjunction with certain HDR color spaces that can + be represented by the cICP chunk. + See the PNG specification, third edition, for more information on this chunk. + The clli_max_cll and clli_max_fall values are 32-bit integers. + */ + unsigned clli_defined; /* Whether a cLLI chunk is present (0 = not present, 1 = present). */ + unsigned clli_max_cll; /* Maximum Content Light Level (MaxCLL) in cd/m^2 times 10000 */ + unsigned clli_max_fall; /* Maximum Frame-Average Light Level (MaxFALL) in cd/m^2 times 10000 */ + + /* + sBIT chunk: significant bits. + Optional metadata, only set this if needed. + + If defined, these values give the bit depth of the original data. Since PNG only stores 1, 2, 4, 8 or 16-bit + per channel data, the significant bits value can be used to indicate the original encoded data has another + sample depth, such as 10 or 12. + + Encoders using this value, when storing the pixel data, should use the most significant bits + of the data to store the original bits, and use a good sample depth scaling method such as + "left bit replication" to fill in the least significant bits, rather than fill zeroes. + + Decoders using this value, if able to work with data that's e.g. 10-bit or 12-bit, should right + shift the data to go back to the original bit depth, but decoders are also allowed to ignore + sbit and work e.g. with the 8-bit or 16-bit data from the PNG directly, since thanks + to the encoder contract, the values encoded in PNG are in valid range for the PNG bit depth. + + For grayscale images, sbit_g and sbit_b are not used, and for images that don't use color + type RGBA or grayscale+alpha, sbit_a is not used (it's not used even for palette images with + translucent palette values, or images with color key). The values that are used must be + greater than zero and smaller than or equal to the PNG bit depth. + + The color type from the header in the PNG image defines these used and unused fields: if + decoding with a color mode conversion, such as always decoding to RGBA, this metadata still + only uses the color type of the original PNG, and may e.g. lack the alpha channel info + if the PNG was RGB. When encoding with auto_convert (as well as without), also always the + color model defined in info_png.color determines this. + + NOTE: enabling sbit can hurt compression, because the encoder can then not always use + auto_convert to choose a more optimal color mode for the data, because the PNG format has + strict requirements for the allowed sbit values in combination with color modes. + For example, setting these fields to 10-bit will force the encoder to keep using a 16-bit per channel + color mode, even if the pixel data would in fact fit in a more efficient 8-bit mode. + */ + unsigned sbit_defined; /*is significant bits given? if not, the values below are unused*/ + unsigned sbit_r; /*red or gray component of significant bits*/ + unsigned sbit_g; /*green component of significant bits*/ + unsigned sbit_b; /*blue component of significant bits*/ + unsigned sbit_a; /*alpha component of significant bits*/ + + /* End of color profile related chunks */ + + + /* + unknown chunks: chunks not known by LodePNG, passed on byte for byte. + + There are 3 buffers, one for each position in the PNG where unknown chunks can appear. + Each buffer contains all unknown chunks for that position consecutively. + The 3 positions are: + 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. + + For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag + above in here, since the encoder will blindly follow this and could then encode an invalid PNG file + (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use + this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST), + or any non-standard PNG chunk. + + Do not allocate or traverse this data yourself. Use the chunk traversing functions declared + later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. + */ + unsigned char* unknown_chunks_data[3]; + size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGInfo; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_info_init(LodePNGInfo* info); +void lodepng_info_cleanup(LodePNGInfo* info); +/*return value is error code (0 means no error)*/ +unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS +unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ +void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ + +unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, + const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ +void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ + +/*replaces if exists*/ +unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size); +void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the profile again after you filled it in*/ + +/*replaces if exists*/ +unsigned lodepng_set_exif(LodePNGInfo* info, const unsigned char* exif, unsigned exif_size); +void lodepng_clear_exif(LodePNGInfo* info); /*use this to clear the exif metadata again after you filled it in*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + +/* +Converts raw buffer from one color type to another color type, based on +LodePNGColorMode structs to describe the input and output color type. +See the reference manual at the end of this header file to see which color conversions are supported. +return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) +The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel +of the output color type (lodepng_get_bpp). +For < 8 bpp images, there should not be padding bits at the end of scanlines. +For 16-bit per channel colors, uses big endian format like PNG does. +Return value is LodePNG error code +*/ +unsigned lodepng_convert(unsigned char* out, const unsigned char* in, + const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h); + +#ifdef LODEPNG_COMPILE_DECODER +/* +Settings for the decoder. This contains settings for the PNG and the Zlib +decoder, but not the Info settings from the Info structs. +*/ +typedef struct LodePNGDecoderSettings { + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + + /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ + unsigned ignore_crc; /*ignore CRC checksums*/ + unsigned ignore_critical; /*ignore unknown critical chunks*/ + unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ + /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable + errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some + strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters + in string keys, invalid characters in chunk types names, etc... */ + + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ + +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ + + /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ + unsigned remember_unknown_chunks; + + /* maximum size for decompressed text chunks. If a text chunk's text is larger than this, an error is returned, + unless reading text chunks is disabled or this limit is set higher or disabled. Set to 0 to allow any size. + By default it is a value that prevents unreasonably large strings from hogging memory. */ + size_t max_text_size; + + /* maximum size for compressed ICC chunks. If the ICC profile is larger than this, an error will be returned. Set to + 0 to allow any size. By default this is a value that prevents ICC profiles that would be much larger than any + legitimate profile could be to hog memory. */ + size_t max_icc_size; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGDecoderSettings; + +void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/*strategy to use to choose the PNG filter per scanline. Strategies 0-4 correspond +to each of the 5 filter types PNG supports, the next values are adaptive strategies*/ +typedef enum LodePNGFilterStrategy { + /*every filter at zero*/ + LFS_ZERO = 0, + /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/ + LFS_ONE = 1, + LFS_TWO = 2, + LFS_THREE = 3, + LFS_FOUR = 4, + /*Use the filter out of the 5 above types that gives minimum sum, by trying each one. This is the adaptive filtering + suggested heuristic in the PNG standard chapter 'Filter selection'.*/ + LFS_MINSUM, + /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending + on the image, this is better or worse than minsum.*/ + LFS_ENTROPY, + /* + Brute-force-search PNG filters by compressing each filter for each scanline. + Experimental, very slow, and only rarely gives better compression than MINSUM. + */ + LFS_BRUTE_FORCE, + /*use predefined_filters buffer: you specify the filter type for each scanline*/ + LFS_PREDEFINED +} LodePNGFilterStrategy; + +/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), +which helps decide which color model to use for encoding. +Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ +typedef struct LodePNGColorStats { + unsigned colored; /*not grayscale*/ + unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ + unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ + unsigned short key_g; + unsigned short key_b; + unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ + unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/ + unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/ + unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/ + size_t numpixels; + + /*user settings for computing/using the stats*/ + unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/ + unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/ +} LodePNGColorStats; + +void lodepng_color_stats_init(LodePNGColorStats* stats); + +/*Get a LodePNGColorStats of the image. The stats must already have been inited. +Returns error code (e.g. alloc fail) or 0 if ok.*/ +unsigned lodepng_compute_color_stats(LodePNGColorStats* stats, + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); + +/*Settings for the encoder.*/ +typedef struct LodePNGEncoderSettings { + LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ + + /*automatically choose output PNG color type. If false, must explicitely choose the output color + type in state.info_png.color.colortype, info_png.color.bitdepth and optionally its palette. + Default: true*/ + unsigned auto_convert; + + /*If true, follows the suggestion in the PNG standard in chapter 'Filter selection': if the PNG uses + a palette or lower than 8 bit depth, set all filters to zero. + In other cases this will use the heuristic from the chosen filter_strategy. The PNG standard + suggests LFS_MINSUM for those cases.*/ + unsigned filter_palette_zero; + /*Which filter strategy to use when not using zeroes due to filter_palette_zero. + Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ + LodePNGFilterStrategy filter_strategy; + /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with + the same length as the amount of scanlines in the image, and each value must <= 5. You + have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero + must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ + const unsigned char* predefined_filters; + + /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). + If colortype is 3, PLTE is always created. If color type is explicitely set + to a grayscale type (1 or 4), this is not done and is ignored. If enabling this, + a palette must be present in the info_png. + NOTE: enabling this may worsen compression if auto_convert is used to choose + optimal color mode, because it cannot use grayscale color modes in this case*/ + unsigned force_palette; +#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS + /*add LodePNG identifier and version as a text chunk, for debugging*/ + unsigned add_id; + /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ + unsigned text_compression; +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ +} LodePNGEncoderSettings; + +void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); +#endif /*LODEPNG_COMPILE_ENCODER*/ + + +#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) +/*The settings, state and information for extended encoding and decoding.*/ +typedef struct LodePNGState { +#ifdef LODEPNG_COMPILE_DECODER + LodePNGDecoderSettings decoder; /*the decoding settings*/ +#endif /*LODEPNG_COMPILE_DECODER*/ +#ifdef LODEPNG_COMPILE_ENCODER + LodePNGEncoderSettings encoder; /*the encoding settings*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; +} LodePNGState; + +/*init, cleanup and copy functions to use with this struct*/ +void lodepng_state_init(LodePNGState* state); +void lodepng_state_cleanup(LodePNGState* state); +void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); +#endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ + +#ifdef LODEPNG_COMPILE_DECODER +/* +Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and +getting much more information about the PNG image and color mode. +*/ +unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); + +/* +Read the PNG header, but not the actual data. This returns only the information +that is in the IHDR chunk of the PNG, such as width, height and color type. The +information is placed in the info_png field of the LodePNGState. +*/ +unsigned lodepng_inspect(unsigned* w, unsigned* h, + LodePNGState* state, + const unsigned char* in, size_t insize); +#endif /*LODEPNG_COMPILE_DECODER*/ + +/* +Reads one metadata chunk (other than IHDR, which is handled by lodepng_inspect) +of the PNG file and outputs what it read in the state. Returns error code on failure. +Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const +to find the desired chunk type, and if non null use lodepng_inspect_chunk (with +chunk_pointer - start_of_file as pos). +Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...). +Ignores unsupported, unknown, non-metadata or IHDR chunks (without error). +Requirements: &in[pos] must point to start of a chunk, must use regular +lodepng_inspect first since format of most other chunks depends on IHDR, and if +there is a PLTE chunk, that one must be inspected before tRNS or bKGD. +*/ +unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, + const unsigned char* in, size_t insize); + +#ifdef LODEPNG_COMPILE_ENCODER +/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ +unsigned lodepng_encode(unsigned char** out, size_t* outsize, + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +/* +The lodepng_chunk functions are normally not needed, except to traverse the +unknown chunks stored in the LodePNGInfo struct, or add new ones to it. +It also allows traversing the chunks of an encoded PNG file yourself. + +The chunk pointer always points to the beginning of the chunk itself, that is +the first byte of the 4 length bytes. + +In the PNG file format, chunks have the following format: +-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) +-4 bytes chunk type (ASCII a-z,A-Z only, see below) +-length bytes of data (may be 0 bytes if length was 0) +-4 bytes of CRC, computed on chunk name + data + +The first chunk starts at the 8th byte of the PNG file, the entire rest of the file +exists out of concatenated chunks with the above format. + +PNG standard chunk ASCII naming conventions: +-First byte: uppercase = critical, lowercase = ancillary +-Second byte: uppercase = public, lowercase = private +-Third byte: must be uppercase +-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy +*/ + +/* +Gets the length of the data of the chunk. Total chunk length has 12 bytes more. +There must be at least 4 bytes to read from. If the result value is too large, +it may be corrupt data. +*/ +unsigned lodepng_chunk_length(const unsigned char* chunk); + +/*puts the 4-byte type in null terminated string*/ +void lodepng_chunk_type(char type[5], const unsigned char* chunk); + +/*check if the type is the given type*/ +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); + +/*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ +unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); + +/*0: public, 1: private (see PNG standard)*/ +unsigned char lodepng_chunk_private(const unsigned char* chunk); + +/*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); + +/*get pointer to the data of the chunk, where the input points to the header of the chunk*/ +unsigned char* lodepng_chunk_data(unsigned char* chunk); +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); + +/*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ +unsigned lodepng_chunk_check_crc(const unsigned char* chunk); + +/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ +void lodepng_chunk_generate_crc(unsigned char* chunk); + +/* +Iterate to next chunks, allows iterating through all chunks of the PNG file. +Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call, +or the 8th byte of a PNG file which always has the first chunk), or alternatively may +point to the first byte of the PNG file (which is not a chunk but the magic header, the +function will then skip over it and return the first real chunk). +Will output pointer to the start of the next chunk, or at or beyond end of the file if there +is no more chunk after this or possibly if the chunk is corrupt. +Start this process at the 8th byte of the PNG file. +In a non-corrupt PNG file, the last chunk should have name "IEND". +*/ +unsigned char* lodepng_chunk_next(unsigned char* chunk, unsigned char* end); +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end); + +/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/ +unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, const char type[5]); +const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]); + +/* +Appends chunk to the data in out. The given chunk should already have its chunk header. +The out variable and outsize are updated to reflect the new reallocated buffer. +Returns error code (0 if it went ok) +*/ +unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk); + +/* +Appends new chunk to out. The chunk to append is given by giving its length, type +and data separately. The type is a 4-letter string. +The out variable and outsize are updated to reflect the new reallocated buffer. +Returne error code (0 if it went ok) +*/ +unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, size_t length, + const char* type, const unsigned char* data); + + +/*Calculate CRC32 of buffer*/ +unsigned lodepng_crc32(const unsigned char* buf, size_t len); +#endif /*LODEPNG_COMPILE_PNG*/ + + +#ifdef LODEPNG_COMPILE_ZLIB +/* +This zlib part can be used independently to zlib compress and decompress a +buffer. It cannot be used to create gzip files however, and it only supports the +part of zlib that is required for PNG, it does not support dictionaries. +*/ + +#ifdef LODEPNG_COMPILE_DECODER +/*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ +unsigned lodepng_inflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); + +/* +Decompresses Zlib data. Reallocates the out buffer and appends the data. The +data must be according to the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* +Compresses data with Zlib. Reallocates the out buffer and appends the data. +Zlib adds a small header and trailer around the deflate data. +The data is output in the format of the zlib specification. +Either, *out must be NULL and *outsize must be 0, or, *out must be a valid +buffer and *outsize its size in bytes. out must be freed by user after usage. +*/ +unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +/* +Find length-limited Huffman code for given frequencies. This function is in the +public interface only for tests, it's used internally by lodepng_deflate. +*/ +unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, + size_t numcodes, unsigned maxbitlen); + +/*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ +unsigned lodepng_deflate(unsigned char** out, size_t* outsize, + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); + +#endif /*LODEPNG_COMPILE_ENCODER*/ +#endif /*LODEPNG_COMPILE_ZLIB*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into buffer. The function allocates the out buffer, and +after usage you should free it. +out: output parameter, contains pointer to loaded buffer. +outsize: output parameter, size of the allocated out buffer +filename: the path to the file to load +return value: error code (0 means ok) + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory. +*/ +unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); + +/* +Save a file from buffer to disk. Warning, if it exists, this function overwrites +the file without warning! +buffer: the buffer to write +buffersize: size of the buffer to write +filename: the path to the file to save to +return value: error code (0 means ok) + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory +*/ +unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); +#endif /*LODEPNG_COMPILE_DISK*/ + +#ifdef LODEPNG_COMPILE_CPP +/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ +namespace lodepng { +#ifdef LODEPNG_COMPILE_PNG +class State : public LodePNGState { + public: + State(); + State(const State& other); + ~State(); + State& operator=(const State& other); +}; + +#ifdef LODEPNG_COMPILE_DECODER +/* Same as other lodepng::decode, but using a State for more settings and information. */ +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const unsigned char* in, size_t insize); +unsigned decode(std::vector& out, unsigned& w, unsigned& h, + State& state, + const std::vector& in); +#endif /*LODEPNG_COMPILE_DECODER*/ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Same as other lodepng::encode, but using a State for more settings and information. */ +unsigned encode(std::vector& out, + const unsigned char* in, unsigned w, unsigned h, + State& state); +unsigned encode(std::vector& out, + const std::vector& in, unsigned w, unsigned h, + State& state); +#endif /*LODEPNG_COMPILE_ENCODER*/ + +#ifdef LODEPNG_COMPILE_DISK +/* +Load a file from disk into an std::vector. +return value: error code (0 means ok) + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and decode in-memory +*/ +unsigned load_file(std::vector& buffer, const std::string& filename); + +/* +Save the binary data in an std::vector to a file on disk. The file is overwritten +without warning. + +NOTE: Wide-character filenames are not supported, you can use an external method +to handle such files and encode in-memory +*/ +unsigned save_file(const std::vector& buffer, const std::string& filename); +#endif /* LODEPNG_COMPILE_DISK */ +#endif /* LODEPNG_COMPILE_PNG */ + +#ifdef LODEPNG_COMPILE_ZLIB +#ifdef LODEPNG_COMPILE_DECODER +/* Zlib-decompress an unsigned char buffer */ +unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); + +/* Zlib-decompress an std::vector */ +unsigned decompress(std::vector& out, const std::vector& in, + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); +#endif /* LODEPNG_COMPILE_DECODER */ + +#ifdef LODEPNG_COMPILE_ENCODER +/* Zlib-compress an unsigned char buffer */ +unsigned compress(std::vector& out, const unsigned char* in, size_t insize, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); + +/* Zlib-compress an std::vector */ +unsigned compress(std::vector& out, const std::vector& in, + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); +#endif /* LODEPNG_COMPILE_ENCODER */ +#endif /* LODEPNG_COMPILE_ZLIB */ +} /* namespace lodepng */ +#endif /*LODEPNG_COMPILE_CPP*/ + +/* +TODO: +[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often +[.] check compatibility with various compilers - done but needs to be redone for every newer version +[X] converting color to 16-bit per channel types +[X] support color profile chunk types (but never let them touch RGB values by default) +[ ] support all second edition public PNG chunk types (almost done except sPLT and hIST) +[X] support non-animation third edition public PNG chunk types: eXIf, cICP, mDCV, cLLI +[ ] make sure encoder generates no chunks with size > (2^31)-1 +[ ] partial decoding (stream processing) +[X] let the "isFullyOpaque" function check color keys and transparent palettes too +[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" +[ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58) +[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... +[ ] error messages with line numbers (and version) +[ ] errors in state instead of as return code? +[ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk +[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes +[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... +[ ] allow user to give data (void*) to custom allocator +[X] provide alternatives for C library functions not present on some platforms (memcpy, ...) +*/ + +#endif /*LODEPNG_H inclusion guard*/ + +/* +LodePNG Documentation +--------------------- + +0. table of contents +-------------------- + + 1. about + 1.1. supported features + 1.2. features not supported + 2. C and C++ version + 3. security + 4. decoding + 5. encoding + 6. color conversions + 6.1. PNG color types + 6.2. color conversions + 6.3. padding bits + 6.4. A note about 16-bits per channel and endianness + 7. error values + 8. chunks and PNG editing + 9. compiler support + 10. examples + 10.1. decoder C++ example + 10.2. decoder C example + 11. state settings reference + 12. changes + 13. contact information + + +1. about +-------- + +PNG is a file format to store raster images losslessly with good compression, +supporting different color types and alpha channel. + +LodePNG is a PNG codec according to the Portable Network Graphics (PNG) +Specification (Second Edition) - W3C Recommendation 10 November 2003. + +The specifications used are: + +*) Portable Network Graphics (PNG) Specification (Second Edition): + http://www.w3.org/TR/2003/REC-PNG-20031110 +*) RFC 1950 ZLIB Compressed Data Format version 3.3: + http://www.gzip.org/zlib/rfc-zlib.html +*) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: + http://www.gzip.org/zlib/rfc-deflate.html + +The most recent version of LodePNG can currently be found at +http://lodev.org/lodepng/ + +LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds +extra functionality. + +LodePNG exists out of two files: +-lodepng.h: the header file for both C and C++ +-lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage + +If you want to start using LodePNG right away without reading this doc, get the +examples from the LodePNG website to see how to use it in code, or check the +smaller examples in chapter 13 here. + +LodePNG is simple but only supports the basic requirements. To achieve +simplicity, the following design choices were made: There are no dependencies +on any external library. There are functions to decode and encode a PNG with +a single function call, and extended versions of these functions taking a +LodePNGState struct allowing to specify or get more information. By default +the colors of the raw image are always RGB or RGBA, no matter what color type +the PNG file uses. To read and write files, there are simple functions to +convert the files to/from buffers in memory. + +This all makes LodePNG suitable for loading textures in games, demos and small +programs, ... It's less suitable for full fledged image editors, loading PNGs +over network (it requires all the image data to be available before decoding can +begin), life-critical systems, ... + +1.1. supported features +----------------------- + +The following features are supported by the decoder: + +*) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, + or the same color type as the PNG +*) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image +*) Adam7 interlace and deinterlace for any color type +*) loading the image from harddisk or decoding it from a buffer from other sources than harddisk +*) support for alpha channels, including RGBA color model, translucent palettes and color keying +*) zlib decompression (inflate) +*) zlib compression (deflate) +*) CRC32 and ADLER32 checksums +*) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only, + plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system. +*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. +*) the following chunks are supported by both encoder and decoder: + IHDR: header information + PLTE: color palette + IDAT: pixel data + IEND: the final chunk + tRNS: transparency for palettized images + tEXt: textual information + zTXt: compressed textual information + iTXt: international textual information + bKGD: suggested background color + pHYs: physical dimensions + tIME: modification time + cHRM: RGB chromaticities + gAMA: RGB gamma correction + iCCP: ICC color profile + sRGB: rendering intent + sBIT: significant bits + +1.2. features not supported +--------------------------- + +The following features are not (yet) supported: + +*) some features needed to make a conformant PNG-Editor might be still missing. +*) partial loading/stream processing. All data must be available and is processed in one call. +*) The hIST and sPLT public chunks are not (yet) supported but treated as unknown chunks + + +2. C and C++ version +-------------------- + +The C version uses buffers allocated with alloc that you need to free() +yourself. You need to use init and cleanup functions for each struct whenever +using a struct from the C version to avoid exploits and memory leaks. + +The C++ version has extra functions with std::vectors in the interface and the +lodepng::State class which is a LodePNGState with constructor and destructor. + +These files work without modification for both C and C++ compilers because all +the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers +ignore it, and the C code is made to compile both with strict ISO C90 and C++. + +To use the C++ version, you need to rename the source file to lodepng.cpp +(instead of lodepng.c), and compile it with a C++ compiler. + +To use the C version, you need to rename the source file to lodepng.c (instead +of lodepng.cpp), and compile it with a C compiler. + + +3. Security +----------- + +Even if carefully designed, it's always possible that LodePNG contains possible +exploits. If you discover one, please let me know, and it will be fixed. + +When using LodePNG, care has to be taken with the C version of LodePNG, as well +as the C-style structs when working with C++. The following conventions are used +for all C-style structs: + +-if a struct has a corresponding init function, always call the init function when making a new one +-if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks +-if a struct has a corresponding copy function, use the copy function instead of "=". + The destination must also be inited already. + + +4. Decoding +----------- + +Decoding converts a PNG compressed image to a raw pixel buffer. + +Most documentation on using the decoder is at its declarations in the header +above. For C, simple decoding can be done with functions such as +lodepng_decode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_decode. For C++, all decoding can be done with the +various lodepng::decode functions, and lodepng::State can be used for advanced +features. + +When using the LodePNGState, it uses the following fields for decoding: +*) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here +*) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get +*) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use + +LodePNGInfo info_png +-------------------- + +After decoding, this contains extra information of the PNG image, except the actual +pixels, width and height because these are already gotten directly from the decoder +functions. + +It contains for example the original color type of the PNG image, text comments, +suggested background color, etc... More details about the LodePNGInfo struct are +at its declaration documentation. + +LodePNGColorMode info_raw +------------------------- + +When decoding, here you can specify which color type you want +the resulting raw image to be. If this is different from the colortype of the +PNG, then the decoder will automatically convert the result. This conversion +always works, except if you want it to convert a color PNG to grayscale or to +a palette with missing colors. + +By default, 32-bit color is used for the result. + +LodePNGDecoderSettings decoder +------------------------------ + +The settings can be used to ignore the errors created by invalid CRC and Adler32 +chunks, and to disable the decoding of tEXt chunks. + +There's also a setting color_convert, true by default. If false, no conversion +is done, the resulting data will be as it was in the PNG (after decompression) +and you'll have to puzzle the colors of the pixels together yourself using the +color type information in the LodePNGInfo. + + +5. Encoding +----------- + +Encoding converts a raw pixel buffer to a PNG compressed image. + +Most documentation on using the encoder is at its declarations in the header +above. For C, simple encoding can be done with functions such as +lodepng_encode32, and more advanced decoding can be done with the struct +LodePNGState and lodepng_encode. For C++, all encoding can be done with the +various lodepng::encode functions, and lodepng::State can be used for advanced +features. + +Like the decoder, the encoder can also give errors. However it gives less errors +since the encoder input is trusted, the decoder input (a PNG image that could +be forged by anyone) is not trusted. + +When using the LodePNGState, it uses the following fields for encoding: +*) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. +*) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has +*) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use + +LodePNGInfo info_png +-------------------- + +When encoding, you use this the opposite way as when decoding: for encoding, +you fill in the values you want the PNG to have before encoding. By default it's +not needed to specify a color type for the PNG since it's automatically chosen, +but it's possible to choose it yourself given the right settings. + +The encoder will not always exactly match the LodePNGInfo struct you give, +it tries as close as possible. Some things are ignored by the encoder. The +encoder uses, for example, the following settings from it when applicable: +colortype and bitdepth, text chunks, time chunk, the color key, the palette, the +background color, the interlace method, unknown chunks, ... + +When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. +If the palette contains any colors for which the alpha channel is not 255 (so +there are translucent colors in the palette), it'll add a tRNS chunk. + +LodePNGColorMode info_raw +------------------------- + +You specify the color type of the raw image that you give to the input here, +including a possible transparent color key and palette you happen to be using in +your raw image data. + +By default, 32-bit color is assumed, meaning your input has to be in RGBA +format with 4 bytes (unsigned chars) per pixel. + +LodePNGEncoderSettings encoder +------------------------------ + +The following settings are supported (some are in sub-structs): +*) auto_convert: when this option is enabled, the encoder will +automatically choose the smallest possible color mode (including color key) that +can encode the colors of all pixels without information loss. +*) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, + 2 = dynamic huffman tree (best compression). Should be 2 for proper + compression. +*) use_lz77: whether or not to use LZ77 for compressed block types. Should be + true for proper compression. +*) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value + 2048 by default, but can be set to 32768 for better, but slow, compression. +*) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE + chunk if force_palette is true. This can used as suggested palette to convert + to by viewers that don't support more than 256 colors (if those still exist) +*) add_id: add text chunk "Encoder: LodePNG " to the image. +*) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. + zTXt chunks use zlib compression on the text. This gives a smaller result on + large texts but a larger result on small texts (such as a single program name). + It's all tEXt or all zTXt though, there's no separate setting per text yet. + + +6. color conversions +-------------------- + +An important thing to note about LodePNG, is that the color type of the PNG, and +the color type of the raw image, are completely independent. By default, when +you decode a PNG, you get the result as a raw image in the color type you want, +no matter whether the PNG was encoded with a palette, grayscale or RGBA color. +And if you encode an image, by default LodePNG will automatically choose the PNG +color type that gives good compression based on the values of colors and amount +of colors in the image. It can be configured to let you control it instead as +well, though. + +To be able to do this, LodePNG does conversions from one color mode to another. +It can convert from almost any color type to any other color type, except the +following conversions: RGB to grayscale is not supported, and converting to a +palette when the palette doesn't have a required color is not supported. This is +not supported on purpose: this is information loss which requires a color +reduction algorithm that is beyond the scope of a PNG encoder (yes, RGB to gray +is easy, but there are multiple ways if you want to give some channels more +weight). + +By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB +color, no matter what color type the PNG has. And by default when encoding, +LodePNG automatically picks the best color model for the output PNG, and expects +the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control +the color format of the images yourself, you can skip this chapter. + +6.1. PNG color types +-------------------- + +A PNG image can have many color types, ranging from 1-bit color to 64-bit color, +as well as palettized color modes. After the zlib decompression and unfiltering +in the PNG image is done, the raw pixel data will have that color type and thus +a certain amount of bits per pixel. If you want the output raw image after +decoding to have another color type, a conversion is done by LodePNG. + +The PNG specification gives the following color types: + +0: grayscale, bit depths 1, 2, 4, 8, 16 +2: RGB, bit depths 8 and 16 +3: palette, bit depths 1, 2, 4 and 8 +4: grayscale with alpha, bit depths 8 and 16 +6: RGBA, bit depths 8 and 16 + +Bit depth is the amount of bits per pixel per color channel. So the total amount +of bits per pixel is: amount of channels * bitdepth. + +6.2. color conversions +---------------------- + +As explained in the sections about the encoder and decoder, you can specify +color types and bit depths in info_png and info_raw to change the default +behaviour. + +If, when decoding, you want the raw image to be something else than the default, +you need to set the color type and bit depth you want in the LodePNGColorMode, +or the parameters colortype and bitdepth of the simple decoding function. + +If, when encoding, you use another color type than the default in the raw input +image, you need to specify its color type and bit depth in the LodePNGColorMode +of the raw image, or use the parameters colortype and bitdepth of the simple +encoding function. + +If, when encoding, you don't want LodePNG to choose the output PNG color type +but control it yourself, you need to set auto_convert in the encoder settings +to false, and specify the color type you want in the LodePNGInfo of the +encoder (including palette: it can generate a palette if auto_convert is true, +otherwise not). + +If the input and output color type differ (whether user chosen or auto chosen), +LodePNG will do a color conversion, which follows the rules below, and may +sometimes result in an error. + +To avoid some confusion: +-the decoder converts from PNG to raw image +-the encoder converts from raw image to PNG +-the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image +-the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG +-when encoding, the color type in LodePNGInfo is ignored if auto_convert + is enabled, it is automatically generated instead +-when decoding, the color type in LodePNGInfo is set by the decoder to that of the original + PNG image, but it can be ignored since the raw image has the color type you requested instead +-if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion + between the color types is done if the color types are supported. If it is not + supported, an error is returned. If the types are the same, no conversion is done. +-even though some conversions aren't supported, LodePNG supports loading PNGs from any + colortype and saving PNGs to any colortype, sometimes it just requires preparing + the raw image correctly before encoding. +-both encoder and decoder use the same color converter. + +The function lodepng_convert does the color conversion. It is available in the +interface but normally isn't needed since the encoder and decoder already call +it. + +Non supported color conversions: +-color to grayscale when non-gray pixels are present: no error is thrown, but +the result will look ugly because only the red channel is taken (it assumes all +three channels are the same in this case so ignores green and blue). The reason +no error is given is to allow converting from three-channel grayscale images to +one-channel even if there are numerical imprecisions. +-anything to palette when the palette does not have an exact match for a from-color +in it: in this case an error is thrown + +Supported color conversions: +-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA +-any gray or gray+alpha, to gray or gray+alpha +-anything to a palette, as long as the palette has the requested colors in it +-removing alpha channel +-higher to smaller bitdepth, and vice versa + +If you want no color conversion to be done (e.g. for speed or control): +-In the encoder, you can make it save a PNG with any color type by giving the +raw color mode and LodePNGInfo the same color mode, and setting auto_convert to +false. +-In the decoder, you can make it store the pixel data in the same color type +as the PNG has, by setting the color_convert setting to false. Settings in +info_raw are then ignored. + +6.3. padding bits +----------------- + +In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines +have a bit amount that isn't a multiple of 8, then padding bits are used so that each +scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. +The raw input image you give to the encoder, and the raw output image you get from the decoder +will NOT have these padding bits, e.g. in the case of a 1-bit image with a width +of 7 pixels, the first pixel of the second scanline will the 8th bit of the first byte, +not the first bit of a new byte. + +6.4. A note about 16-bits per channel and endianness +---------------------------------------------------- + +LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like +for any other color format. The 16-bit values are stored in big endian (most +significant byte first) in these arrays. This is the opposite order of the +little endian used by x86 CPU's. + +LodePNG always uses big endian because the PNG file format does so internally. +Conversions to other formats than PNG uses internally are not supported by +LodePNG on purpose, there are myriads of formats, including endianness of 16-bit +colors, the order in which you store R, G, B and A, and so on. Supporting and +converting to/from all that is outside the scope of LodePNG. + +This may mean that, depending on your use case, you may want to convert the big +endian output of LodePNG to little endian with a for loop. This is certainly not +always needed, many applications and libraries support big endian 16-bit colors +anyway, but it means you cannot simply cast the unsigned char* buffer to an +unsigned short* buffer on x86 CPUs. + + +7. error values +--------------- + +All functions in LodePNG that return an error code, return 0 if everything went +OK, or a non-zero code if there was an error. + +The meaning of the LodePNG error values can be retrieved with the function +lodepng_error_text: given the numerical error code, it returns a description +of the error in English as a string. + +Check the implementation of lodepng_error_text to see the meaning of each code. + +It is not recommended to use the numerical values to programmatically make +different decisions based on error types as the numbers are not guaranteed to +stay backwards compatible. They are for human consumption only. Programmatically +only 0 or non-0 matter. + + +8. chunks and PNG editing +------------------------- + +If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG +editor that should follow the rules about handling of unknown chunks, or if your +program is able to read other types of chunks than the ones handled by LodePNG, +then that's possible with the chunk functions of LodePNG. + +A PNG chunk has the following layout: + +4 bytes length +4 bytes type name +length bytes data +4 bytes CRC + +8.1. iterating through chunks +----------------------------- + +If you have a buffer containing the PNG image data, then the first chunk (the +IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the +signature of the PNG and are not part of a chunk. But if you start at byte 8 +then you have a chunk, and can check the following things of it. + +NOTE: none of these functions check for memory buffer boundaries. To avoid +exploits, always make sure the buffer contains all the data of the chunks. +When using lodepng_chunk_next, make sure the returned value is within the +allocated memory. + +unsigned lodepng_chunk_length(const unsigned char* chunk): + +Get the length of the chunk's data. The total chunk length is this length + 12. + +void lodepng_chunk_type(char type[5], const unsigned char* chunk): +unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): + +Get the type of the chunk or compare if it's a certain type + +unsigned char lodepng_chunk_critical(const unsigned char* chunk): +unsigned char lodepng_chunk_private(const unsigned char* chunk): +unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): + +Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). +Check if the chunk is private (public chunks are part of the standard, private ones not). +Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical +chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your +program doesn't handle that type of unknown chunk. + +unsigned char* lodepng_chunk_data(unsigned char* chunk): +const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): + +Get a pointer to the start of the data of the chunk. + +unsigned lodepng_chunk_check_crc(const unsigned char* chunk): +void lodepng_chunk_generate_crc(unsigned char* chunk): + +Check if the crc is correct or generate a correct one. + +unsigned char* lodepng_chunk_next(unsigned char* chunk): +const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): + +Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these +functions do no boundary checking of the allocated data whatsoever, so make sure there is enough +data available in the buffer to be able to go to the next chunk. + +unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk): +unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length, + const char* type, const unsigned char* data): + +These functions are used to create new chunks that are appended to the data in *out that has +length *outsize. The append function appends an existing chunk to the new data. The create +function creates a new chunk with the given parameters and appends it. Type is the 4-letter +name of the chunk. + +8.2. chunks in info_png +----------------------- + +The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 +buffers (each with size) to contain 3 types of unknown chunks: +the ones that come before the PLTE chunk, the ones that come between the PLTE +and the IDAT chunks, and the ones that come after the IDAT chunks. +It's necessary to make the distinction between these 3 cases because the PNG +standard forces to keep the ordering of unknown chunks compared to the critical +chunks, but does not force any other ordering rules. + +info_png.unknown_chunks_data[0] is the chunks before PLTE +info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT +info_png.unknown_chunks_data[2] is the chunks after IDAT + +The chunks in these 3 buffers can be iterated through and read by using the same +way described in the previous subchapter. + +When using the decoder to decode a PNG, you can make it store all unknown chunks +if you set the option settings.remember_unknown_chunks to 1. By default, this +option is off (0). + +The encoder will always encode unknown chunks that are stored in the info_png. +If you need it to add a particular chunk that isn't known by LodePNG, you can +use lodepng_chunk_append or lodepng_chunk_create to the chunk data in +info_png.unknown_chunks_data[x]. + +Chunks that are known by LodePNG should not be added in that way. E.g. to make +LodePNG add a bKGD chunk, set background_defined to true and add the correct +parameters there instead. + + +9. compiler support +------------------- + +No libraries other than the current standard C library are needed to compile +LodePNG. For the C++ version, only the standard C++ library is needed on top. +Add the files lodepng.c(pp) and lodepng.h to your project, include +lodepng.h where needed, and your program can read/write PNG files. + +It is compatible with C90 and up, and C++03 and up. + +If performance is important, use optimization when compiling! For both the +encoder and decoder, this makes a large difference. + +Make sure that LodePNG is compiled with the same compiler of the same version +and with the same settings as the rest of the program, or the interfaces with +std::vectors and std::strings in C++ can be incompatible. + +CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. + +*) gcc and g++ + +LodePNG is developed in gcc so this compiler is natively supported. It gives no +warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ +version 4.7.1 on Linux, 32-bit and 64-bit. + +*) Clang + +Fully supported and warning-free. + +*) Mingw + +The Mingw compiler (a port of gcc for Windows) should be fully supported by +LodePNG. + +*) Visual Studio and Visual C++ Express Edition + +LodePNG should be warning-free with warning level W4. Two warnings were disabled +with pragmas though: warning 4244 about implicit conversions, and warning 4996 +where it wants to use a non-standard function fopen_s instead of the standard C +fopen. + +Visual Studio may want "stdafx.h" files to be included in each source file and +give an error "unexpected end of file while looking for precompiled header". +This is not standard C++ and will not be added to the stock LodePNG. You can +disable it for lodepng.cpp only by right clicking it, Properties, C/C++, +Precompiled Headers, and set it to Not Using Precompiled Headers there. + +NOTE: Modern versions of VS should be fully supported, but old versions, e.g. +VS6, are not guaranteed to work. + +*) Compilers on Macintosh + +LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for +C and C++. + +*) Other Compilers + +If you encounter problems on any compilers, feel free to let me know and I may +try to fix it if the compiler is modern and standards compliant. + + +10. examples +------------ + +This decoder example shows the most basic usage of LodePNG. More complex +examples can be found on the LodePNG website. + +NOTE: these examples do not support wide-character filenames, you can use an +external method to handle such files and encode or decode in-memory + +10.1. decoder C++ example +------------------------- + +#include "lodepng.h" +#include + +int main(int argc, char *argv[]) { + const char* filename = argc > 1 ? argv[1] : "test.png"; + + //load and decode + std::vector image; + unsigned width, height; + unsigned error = lodepng::decode(image, width, height, filename); + + //if there's an error, display it + if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; + + //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... +} + +10.2. decoder C example +----------------------- + +#include "lodepng.h" + +int main(int argc, char *argv[]) { + unsigned error; + unsigned char* image; + size_t width, height; + const char* filename = argc > 1 ? argv[1] : "test.png"; + + error = lodepng_decode32_file(&image, &width, &height, filename); + + if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); + + / * use image here * / + + free(image); + return 0; +} + +11. state settings reference +---------------------------- + +A quick reference of some settings to set on the LodePNGState + +For decoding: + +state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums +state.decoder.zlibsettings.custom_...: use custom inflate function +state.decoder.ignore_crc: ignore CRC checksums +state.decoder.ignore_critical: ignore unknown critical chunks +state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors +state.decoder.color_convert: convert internal PNG color to chosen one +state.decoder.read_text_chunks: whether to read in text metadata chunks +state.decoder.remember_unknown_chunks: whether to read in unknown chunks +state.info_raw.colortype: desired color type for decoded image +state.info_raw.bitdepth: desired bit depth for decoded image +state.info_raw....: more color settings, see struct LodePNGColorMode +state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo + +For encoding: + +state.encoder.zlibsettings.btype: disable compression by setting it to 0 +state.encoder.zlibsettings.use_lz77: use LZ77 in compression +state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize +state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match +state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching +state.encoder.zlibsettings.lazymatching: try one more LZ77 matching +state.encoder.zlibsettings.custom_...: use custom deflate function +state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png +state.encoder.filter_palette_zero: PNG filter strategy for palette +state.encoder.filter_strategy: PNG filter strategy to encode with +state.encoder.force_palette: add palette even if not encoding to one +state.encoder.add_id: add LodePNG identifier and version as a text chunk +state.encoder.text_compression: use compressed text chunks for metadata +state.info_raw.colortype: color type of raw input image you provide +state.info_raw.bitdepth: bit depth of raw input image you provide +state.info_raw: more color settings, see struct LodePNGColorMode +state.info_png.color.colortype: desired color type if auto_convert is false +state.info_png.color.bitdepth: desired bit depth if auto_convert is false +state.info_png.color....: more color settings, see struct LodePNGColorMode +state.info_png....: more PNG related settings, see struct LodePNGInfo + + +12. changes +----------- + +The version number of LodePNG is the date of the change given in the format +yyyymmdd. + +Some changes aren't backwards compatible. Those are indicated with a (!) +symbol. + +Not all changes are listed here, the commit history in github lists more: +https://github.com/lvandeve/lodepng + +*) 6 may 2025: renamed mDCv to mDCV and cLLi to cLLI as per the recent rename + in the draft png third edition spec. Please note that while the third + edition is not finalized, backwards-incompatible changes to its features are + possible. +*) 23 dec 2024: added support for the mDCv and cLLi chunks (for png third + edition spec) +*) 22 dec 2024: added support for the cICP chunk (for png third edition spec) +*) 15 dec 2024: added support for the eXIf chunk (for png third edition spec) +*) 10 apr 2023: faster CRC32 implementation, but with larger lookup table. +*) 13 jun 2022: added support for the sBIT chunk. +*) 09 jan 2022: minor decoder speed improvements. +*) 27 jun 2021: added warnings that file reading/writing functions don't support + wide-character filenames (support for this is not planned, opening files is + not the core part of PNG decoding/decoding and is platform dependent). +*) 17 oct 2020: prevent decoding too large text/icc chunks by default. +*) 06 mar 2020: simplified some of the dynamic memory allocations. +*) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct + overflow checks. +*) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables. +*) 15 jun 2019: (!) auto_choose_color API changed (for bugfix: don't use palette + if gray ICC profile) and non-ICC LodePNGColorProfile renamed to + LodePNGColorStats. +*) 30 dec 2018: code style changes only: removed newlines before opening braces. +*) 10 sep 2018: added way to inspect metadata chunks without full decoding. +*) 19 aug 2018: (!) fixed color mode bKGD is encoded with and made it use + palette index in case of palette. +*) 10 aug 2018: (!) added support for gAMA, cHRM, sRGB and iCCP chunks. This + change is backwards compatible unless you relied on unknown_chunks for those. +*) 11 jun 2018: less restrictive check for pixel size integer overflow +*) 14 jan 2018: allow optionally ignoring a few more recoverable errors +*) 17 sep 2017: fix memory leak for some encoder input error cases +*) 27 nov 2016: grey+alpha auto color model detection bugfix +*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). +*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within + the limits of pure C90). +*) 08 dec 2015: Made load_file function return error if file can't be opened. +*) 24 oct 2015: Bugfix with decoding to palette output. +*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. +*) 24 aug 2014: Moved to github +*) 23 aug 2014: Reduced needless memory usage of decoder. +*) 28 jun 2014: Removed fix_png setting, always support palette OOB for + simplicity. Made ColorProfile public. +*) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. +*) 22 dec 2013: Power of two windowsize required for optimization. +*) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. +*) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). +*) 11 mar 2013: (!) Bugfix with custom free. Changed from "my" to "lodepng_" + prefix for the custom allocators and made it possible with a new #define to + use custom ones in your project without needing to change lodepng's code. +*) 28 jan 2013: Bugfix with color key. +*) 27 oct 2012: Tweaks in text chunk keyword length error handling. +*) 8 oct 2012: (!) Added new filter strategy (entropy) and new auto color mode. + (no palette). Better deflate tree encoding. New compression tweak settings. + Faster color conversions while decoding. Some internal cleanups. +*) 23 sep 2012: Reduced warnings in Visual Studio a little bit. +*) 1 sep 2012: (!) Removed #define's for giving custom (de)compression functions + and made it work with function pointers instead. +*) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc + and free functions and toggle #defines from compiler flags. Small fixes. +*) 6 may 2012: (!) Made plugging in custom zlib/deflate functions more flexible. +*) 22 apr 2012: (!) Made interface more consistent, renaming a lot. Removed + redundant C++ codec classes. Reduced amount of structs. Everything changed, + but it is cleaner now imho and functionality remains the same. Also fixed + several bugs and shrunk the implementation code. Made new samples. +*) 6 nov 2011: (!) By default, the encoder now automatically chooses the best + PNG color model and bit depth, based on the amount and type of colors of the + raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. +*) 9 oct 2011: simpler hash chain implementation for the encoder. +*) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. +*) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. + A bug with the PNG filtertype heuristic was fixed, so that it chooses much + better ones (it's quite significant). A setting to do an experimental, slow, + brute force search for PNG filter types is added. +*) 17 aug 2011: (!) changed some C zlib related function names. +*) 16 aug 2011: made the code less wide (max 120 characters per line). +*) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. +*) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. +*) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman + to optimize long sequences of zeros. +*) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and + LodePNG_InfoColor_canHaveAlpha functions for convenience. +*) 7 nov 2010: added LodePNG_error_text function to get error code description. +*) 30 oct 2010: made decoding slightly faster +*) 26 oct 2010: (!) changed some C function and struct names (more consistent). + Reorganized the documentation and the declaration order in the header. +*) 08 aug 2010: only changed some comments and external samples. +*) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. +*) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. +*) 02 sep 2008: fixed bug where it could create empty tree that linux apps could + read by ignoring the problem but windows apps couldn't. +*) 06 jun 2008: added more error checks for out of memory cases. +*) 26 apr 2008: added a few more checks here and there to ensure more safety. +*) 06 mar 2008: crash with encoding of strings fixed +*) 02 feb 2008: support for international text chunks added (iTXt) +*) 23 jan 2008: small cleanups, and #defines to divide code in sections +*) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. +*) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. +*) 17 jan 2008: ability to encode and decode compressed zTXt chunks added + Also various fixes, such as in the deflate and the padding bits code. +*) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved + filtering code of encoder. +*) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A + C++ wrapper around this provides an interface almost identical to before. + Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code + are together in these files but it works both for C and C++ compilers. +*) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks +*) 30 aug 2007: bug fixed which makes this Borland C++ compatible +*) 09 aug 2007: some VS2005 warnings removed again +*) 21 jul 2007: deflate code placed in new namespace separate from zlib code +*) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images +*) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing + invalid std::vector element [0] fixed, and level 3 and 4 warnings removed +*) 02 jun 2007: made the encoder add a tag with version by default +*) 27 may 2007: zlib and png code separated (but still in the same file), + simple encoder/decoder functions added for more simple usage cases +*) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), + moved some examples from here to lodepng_examples.cpp +*) 12 may 2007: palette decoding bug fixed +*) 24 apr 2007: changed the license from BSD to the zlib license +*) 11 mar 2007: very simple addition: ability to encode bKGD chunks. +*) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding + palettized PNG images. Plus little interface change with palette and texts. +*) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. + Fixed a bug where the end code of a block had length 0 in the Huffman tree. +*) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented + and supported by the encoder, resulting in smaller PNGs at the output. +*) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. +*) 24 jan 2007: gave encoder an error interface. Added color conversion from any + greyscale type to 8-bit greyscale with or without alpha. +*) 21 jan 2007: (!) Totally changed the interface. It allows more color types + to convert to and is more uniform. See the manual for how it works now. +*) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: + encode/decode custom tEXt chunks, separate classes for zlib & deflate, and + at last made the decoder give errors for incorrect Adler32 or Crc. +*) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. +*) 29 dec 2006: Added support for encoding images without alpha channel, and + cleaned out code as well as making certain parts faster. +*) 28 dec 2006: Added "Settings" to the encoder. +*) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. + Removed some code duplication in the decoder. Fixed little bug in an example. +*) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. + Fixed a bug of the decoder with 16-bit per color. +*) 15 oct 2006: Changed documentation structure +*) 09 oct 2006: Encoder class added. It encodes a valid PNG image from the + given image buffer, however for now it's not compressed. +*) 08 sep 2006: (!) Changed to interface with a Decoder class +*) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different + way. Renamed decodePNG to decodePNGGeneric. +*) 29 jul 2006: (!) Changed the interface: image info is now returned as a + struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. +*) 28 jul 2006: Cleaned the code and added new error checks. + Corrected terminology "deflate" into "inflate". +*) 23 jun 2006: Added SDL example in the documentation in the header, this + example allows easy debugging by displaying the PNG and its transparency. +*) 22 jun 2006: (!) Changed way to obtain error value. Added + loadFile function for convenience. Made decodePNG32 faster. +*) 21 jun 2006: (!) Changed type of info vector to unsigned. + Changed position of palette in info vector. Fixed an important bug that + happened on PNGs with an uncompressed block. +*) 16 jun 2006: Internally changed unsigned into unsigned where + needed, and performed some optimizations. +*) 07 jun 2006: (!) Renamed functions to decodePNG and placed them + in LodePNG namespace. Changed the order of the parameters. Rewrote the + documentation in the header. Renamed files to lodepng.cpp and lodepng.h +*) 22 apr 2006: Optimized and improved some code +*) 07 sep 2005: (!) Changed to std::vector interface +*) 12 aug 2005: Initial release (C++, decoder only) +*/ diff --git a/penpad b/penpad new file mode 100644 index 0000000000000000000000000000000000000000..2b09404ac292ec63ba6f1bed0848f93679aeb5f7 GIT binary patch literal 643984 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ΞH}kg}pw)P;eIAr}nfm2Zf? zLg&q0Z&;C0AfzmrOjM>Pi^^nviZfK74Qt`kB$c<{({u6N_spSnfjjPLF24JoOxy!Y z@O}7T5%hx`{e z*PAgvys{z?(Qkzn4J0XlPO2VT3ZtKHBhXuQJ9zHl2 zvmN#XRgoMttf);68X(j(P&*_ADf!pUB+ssf1*fZK?9KkW^Rl0S?6hQwED^2iVEyv9 zfFD#6bJ6xHd~Dr$2uO``+6WZ@T$!}HzLMgXhGDE z9y>{jpUh+2)ngp$-DmbupEH_WVr!Mx;6;vGJMyxV)r)T4*g@C_TaGe-4+~+zO{UJm z6Sddj$dIi{S&1|Ob-V}`&y<#vp4dmYrt#bE8UV_QzluHZxqCk14>}7zEu7xNcsL==bkp`YACG4*|Ww z&yRRQtY-?^WDT6L=ESQEa334d9v z35Vdb5DQ#4!2)K{bNW~#<~a1d?F;tXn$k=7yg6Lddc)SAe?tG^tAq6rOP9)Y2F;B{ zRAyCWOJiva%w3%jC$tc~kX*WQJKrC>j(!A{5&o_NUr!2(lJylxShR0863FLlM~KaL-F5*ro+d~MD_G=-nyOS4@VGLSa26|&OQRCe+ho~dRGCim$!Kta zWiR*PVQ=c!sMoqaVrTms!nQ3N1T=rPa+0zA$@K ztT7$1iI{SpMpId*_aZ0|Y{2z;yak=^>%#Ft0rF@7f1W8=#n0@MH={BYV{w<(YY|2j zRHk#oX+G(_hhUX$55;)&=IIT`YZCcy&)w%O1KtDl-+~@itbZ)1C+X~#W6o|XzqdDm zqGTHPxl9o;YW6gyS7m>S8TS4?9Y%ayzlv|`Z{CbucH-FLlKtjf^H+g@mTxEFfD6!q zuN?<%=f|rGrPBD4DL#OUio*QLS&m`l2bop(RAqPPw_vXI5PovWR^vsEZ}x1P5CV&E zBs^j~%`%ofmC`i(tIJy9oko}VdAWhCEwH65yfp=}FP_Azhyhvyt&F(D3*|$3F6>}- zoX}XP8p@4P2*b#db=OK!fv~%PIG9WPqjFcSew1hAm|HLIyqbHZ-QL3uSa?gjR~xy| zk+xIKLwd*h3fW|^OSe20Q8%92NfJG+QdN7#-a)G*2Zdc;#aE>|F82_;FyFnslWamn*<{y&e|W;^c~^w3xJ}nJzJ1>a9iRAyh-(#hz?wwQrH*x9xc| zH}OG9q&3Snvy;FY`X0iy=#d z>5kawj+)IS&J6NCJmwr_#okDrOB`0oYBsqv>{hdeZAO`eLSH~$10-kck}Nlzu!%V7 zUDR73)DR8&vVO;|#u#a}hVZb_^t!n#a-MF-$b3?SHJQgN((4Sh|+~1vJiulxLS^(&|_j;mJk? z_Jv%q5Ns+kRYNOg(M){OBCnQhWXhiF5leX@|D`P^>kRV|&LVdh`1@jI&&pXb*%P66 z#biCjVrKu#z7KEsd}&WpBI$f9djD}RtUN2I?~5GTZEcz?6Bfaq5G%~Ok3E4Catmka ze1z|z$I>d|LdTiC`O+%6zk@y3lufcS`7OA_=gS^RI7OPskO}+*V|kj7u&kN%Lr&;l zDCvhjq#wFOBgJ*bN*H);ed8>b_-d675tI7w87l_u(W2(J#}~)m*vI{1Iqq@W^gV=+ zT3zDsGBy}`cR?OxtYUpG=^46p=2rtd2|TS(>F8}A0E#5Lk_ItN(jeg32@PV^rK+SU zcjzK6u~V5$Po8D}y6akt*jj^jbOXS{@s^c-Sox2GX0kicCwPS9O;A9-s5uHm(gHKgdDGcM4-kV_@5!G z#|d7R+t#LvSrwTS>FCdG^c5}QoErK&8S5?2RdBF-b}LwGM1J9i`GnDqt>hPQ7iEwa zl85k#d!_!G?dhZv{x*kb5tmozXQx2oe`KlbMbf$8wigNV@mORlPK)?zHH{IlL|Qe0 zO;6HAXk|uTHQ|H}OXas02yZTx*Eu?_n#{m=Em(SHA3=nu0(1Y+*m_qHt(vR{^kem^acDZoPrak<1vm86|`2tlqEu>|%jKL=ZsmlZ2i!loQ2bnmdb?GHMutztFj z8Z_(>%373Elth$h6oz7OYM9r@*z>s+@eEMf@ail{RqZoQz^?rr@Cx?ID#9g28!o}F zSFDc(F0BAA6-!SN4Sq%T!FF8ol5j~M;x(0Kcj7doi|)mxr`@;|e{d6@HO)5w$ddOw(&id5k1G|I8{y^D|$*)vw? zRWv)aG7VnLGwD0vp#-iQP%tl>EN>ReBRq#(BbaGv%wqfSjj835HZtI1D%oQih}Rx3 zdNC-(v;^xdB&nZ)Z&u9Ad*5ymtVILNSZM%cWor%T51_ljh=-5W9lgRc{M4ByNQ=+d zNM@uM)oxE4ofQ^^H!RW{>-IrMp!W^QQ3x3pdKbO*gCd&Gk77N@V%g4*hd*pIN>O4gj3X9U5Es?)#eR>jhTd#Z;_`2e(yxTyI1fQI{NOQGt&0MFuq$czVAr- z{!E(F?xXL!M4yTtPA;-Co8l^cUlfy0-@8KBD>wB#jn>g3p5G45b{l3*POvPcm_>2I z{H3Ie?k|mlywk0u4}X;32KxZ)Y0!5_9||>f&KYRMTHRbWxZak)pN7=bt%Ph|kMI_I zOa_bi8XlH}DeGb5_Hzd7)*BAnQq82<{Iaw%o1hhy6O$q7k^1Lh*WGqY!yFFKz`&E% zEs&1!g)as04W^hGorKVapROwX34>#o!UhEyd8Q;Ihnn~)Rd)J{hYNYK0Zw2M8;}i* zWVF%tihHMjJIPaLknCwRkapQ zHB#Ff=gbSZ;uBy!Z zZ0Ot@$nVChUAo#|`%xE?uPU6fd{s3|UXP%)h!?6BWX{hbOTpS?E;6V_U0cjlBUIFr zSOucu9IB{Fri$Sdv5kv`tAm&M%x01TXYQg4Y7aV>{+&FuFlNb-fSBx2vja>mVnKDA zlpicvujILWf#Y(!-`Z^~DXaWnVaY$MFcLY`FO9+LFzp3%U0hRfWqKoeRhOrnp>(a5Pm7XclOT4toN$a z)|q{6EphIaPT$c|oX{%y5VVNh{uUAyv&t^fY%-$5EKT2}yfiy>6CXXZGVL1H>sv?4 z97q15T<9|Ab`hqNC6#zzIqBo>ugK3P3JJvuaJ+-f%uj=T&25`45E3l6Juiq#;432e zp5$OoV&LtcT_R4iK0#YECf&!1`3_p2MGx6zq&#~>Gs`uByOKu|mG&Zhrc+JwLmbM{M1;r7`LCfyk&35nKP^ z(m2@sa%X5R=Fa&Du_in7N@Rzz+&H)s?rlNCu}dH<0oZ7peA^1 zR1-88-UZE8v8gRdZX@W3ptK!CTnW%u02z$+Srf&EmffJ_SrmUU`z=j4U0%0nBRiYAUj} zBl^kffy5KL!qRQQx(u}s%WVuvOlqMLKJylRMHYD3h?NOF&KPN3LbBhgh25={SzC~A zpdu@Rp7P~}u7oAmQ?aeqQ`;5(1S@Y!R2OeY*V;nn4O4Z3y>T2^wP<)(}SG_yI z_bw?FngKMB)e?-%ZWt|eydqI%i>Q$(mwGpyYzb~`Uf{U36E=&3(-RdP=E4^78Z=Z` zKwhHn$Jpam^()Jc*< zv-nXB&0?QQPs9mJIy_Nyoq4y2=c`HfZs^cocrsdA#GIOr9Im0VO%rp8{UizDJGaJ; zoJYlkSzG>=f-7L%sjcaB7mschAD65JGGAyGlWJJa!^n5u2j%-~8ny|U0?jCCS3sAD z@%PFuq9U@4yF?YRo-q0KrrVgDxVvIjwHuQ$ZYzmXlMMWTtr`+=Lc0V!2KGh0d0=20 zHjiv#rFvjeJV40dJ@MD|}^f&Hc0H27D03%VxL{+R5~_%T_)d5Z^D zf{=}*;r?+>;; zh3NAYF&ZN7-cKY$Ia zS?u3D=#RX+uKfmlqvwIOlOenuY!Isr579W&39NnoF>@Ce= z{=xiAP2F0>yexkcH?U8QQkqfxP5$Pdy}O!vnX4|-z0KnD2iF_sJ9bO9^k&4rre9mc zmn8|bSxkZKLOna(vWEJJrh-38kezK!RT%8LeXv@r7B;$l4m_+!_qB*7$$Ph1 z94WQdEDk>ylTB-06X3_?Eu=JBp)WAx^CoFJpnW#Vlk5;Or&|C`Xk5(T!1K9cS2 zBwu=I2;Tm2742H2-X=gofQ`}puGZ>#(s$=(bv1EeeQG#qcJ6BGYS#AlHF=pUW|d!R zhiC^&XtVfRwG5F9)xGY){ZrMzF!*N>cQf&c3Du5oFw++M62~kIBw5kRG}iIrZj6F+ z#vdKO_SXhqU?2FVF2JNf7UWRGu~C6WeC!$~T-LBle`r`b%HQ`oZ{{lMwNu_bxKTCv zl-%Yqr)g6!v%e8>z<0?UzFA!8{*JtANuPiQV5zRS3#(|BpYNEnyN#M>fiKe6-)SAj z_`BPhQr!{1{@o1vcWXgv;REQ(ZG3m3W4MG#-`izaj;L;XLzG0DrP3Vh6Y|e?`)P|f zrsD50br?~HuK%?^Ug1W|UJuDuf_T;CyKI)BC&C4tl590`F(j?` zj96CV8LmE4QTH4yQsh<9-v+w{{7GdC4}Iqv*f6HU0?{+43o?ig>|(REAkrw|d6-+9 zKV_4@?|79CxHzE^`!6MGIwav}vshJy9`a@QyLSY2Xg(D~i^%0h>7udJ_(ak%yn zpC03A+;gwS@~fn=yz7*y_-C80!SOvEuRVJipNKZ>%+x9fW70G#4*)Jd5*L2iISM ze2C)nJM2ZjX;=t~A4=QzXKp75wMgIKjp!h4aAF7Bbc9xMPB|A!eW6*!B}N~t$b#Nb zR-W~d;h^K0ZRJ@n1U^nulCRf&rKB*)HeZniJHiMO*4-d<}7{b?Uf~$xB{b` zDDA9Rry6_HYfnsebQ&T>8RMO*$TnVKcJujJ;NmKw+-*tl0~c==f2g@XPk7Y*OrrZQ zU-|d?P>X2AKC=69mw}b;@pm?hD{DZ%j@f(Hkf%~^EcUB=3;#eQ>W3v-Z}U^4UF%-h zwT=v5HGaYajek!Oc{5wZcsF&`R~&KU9`f+|Q*SZ{o=BPRu*oC>Ty%*8w4BaaMP%EruDwlxM7V7x+qTC?!x z&$}qfr=MVPB42jcIB-Ame;PqvMc}Iz;pu`qZ6Cq>V4a`vHtb-2Z&~Vw!0EkM=v2d(S6S55xS_b`PY;)=laLBcyI8N_9}5aFkC@4X>z1KL z7CIum&{?VX5sD;vx*>Ce*$^-y<7nV|Lr?2X;un&=Kh8G!p3w-bSz}n@=F83QQFoS? zr;kYY5#XU2_KQtZSEbCK(VM4rC_U^XSmoxM%&J;d53k5R#s?9tUWGmKe!_$J9$5K9 zI6lk-cSqB7})IE4g8+;Zak5g=YuBk?ipV<56xHA1o(px4vW>BsU}W z3PkGU^P}~L{3}zt3eML2IVyO5ZA_)N3^cR;f&9^{Y-%Ur47>|cf?#ziXoN3Gajd_w z$hjjqi9gJTU>%cTuV_O$gNMjh7GxXV+;RnO(0pi4f!*o zXGG80UaRGd;G}x+GE2!aem~!X_q+JsFB-NGWeSQ9%DxL4_9ZsQ{rI|y#RbhV(Jl*a zOmMEMR_pl~Y*p7R(DD#73hM*d|G|XcEI&xQGOnBq18#rd)@J{(eKuhz{7s&f{7nD> z^vqI19w+~~NMo?RLBacmjlIi!qfXq$f0Agijsq|3 z2!62rBeOH}vA_ak^!vx&d9<=2yq?k3sq>{#TI3kCcLqEenedV2u^{*WW_Qi$&2yph z>PDyiL}lOG%&>RgUjKRhvJT^B(IZ!yWRa?b6rmEXxb@#dwrAS!CNA>g<>P$L<#0ZK z4qzTToPU;I1Iyg$n%=zU;6b#%Ce#DFZq^&V+81J-jMbU0IY$v|hQ{bwnsrNpVMENf z8WWy9O*t03YJIR?aBX=6@P3IA@5M(>)$?^-t5y$8?33KqP2 zF%R1`ubqlXf3^=K1z^k5@K7cn)hSk4ma4Z8xrb(Bt4Ebqrbm>PW%&rporE8%GfC)C zaqMBf_;Ps`H&k=;o1E)n!1cCY=Ut{K4m2}2iEqMwwL(A5-X>#mWz<^_njP!H;GNhy zQia%p@QRC8T?~Ysg0OX3tCc+0;JHZl2)|ydjEn7018zHE<(X}#uS#wC0K3iU4MVW* zq(7%&*UoC#G8D(ppc5276nb+JzPTdZ-_XPAHMpCtGK+jz;m_808ltSwmn+?0?vUDj zxJ9s|RbLPLaegxK4&ZcTi%X1^WW^?N0P5Q$JiY1G*GZdliMu2#R+G3|(!ZO;x7>f1 zL#swq2jpK$2WDy`2-bDv8b zRn|6Jw&|#_z(7VIj8q99OA=0-ruN0|vi21R($t#8e^iG9j_*mcW0P0`uUv;@i)^^d zJ`X#CBzL?G%C3^`IC$3`ZS&3!x6Qqy7r-1?|K6qhb#3bivGqmLF2_WY8QRw)UcO5! z=$Sj?ME=~b_Q~r2FGq}~9eH=?7Z2U>Jnw$~A0234UP(~ZX|!@H^CJ35t;qUGK!@j> zvHnkUZpO7VX7TfizqfeX5Bgyb&o7qs#3#j+nvObRm^nbQXP|9gth~mMRpWJYQ15Q0Wrkj6 zvX#wujFV<#(#mX|=}1767*n$eHW(hc6^UQb z8x-ypY8mHpp>>aPyuMxH1n>yB1gUyO!^%52f$aOQbgDKri!YbA>6^`BMF&~fd|wH^ zNgVHnol%0>7mY2D<9mWXBUctYO#7C-(msztG)Som@(Ho%j$QTM5;LbEvn(4v>T_deRHj2}m`hSxe~HI& zkj!IAItw8Q&=dI}3_(M!r2n3-Vf}p04k#B2$~9dV|8+GS7D=7)x>$1cCrH!=_|{iuSD4U-f{QXtjgF{H`!{IWdrPx; z2;8`FmRzs61N-l_<+;SBs`ZA4tod2B<+p9wLhtWco!AW(X*{pm?ZIpLb%?>`E&Q|D804{c5+WOYR%e;?kSW77;zS6q3J$}y*C3^j zuqt-KD;_I$j}hFNj`tC=AbD$RRD3sN04g(ZR!_mBH6ZZ;cYGe?7aS(X=jn|M9-Yt^ z#O7HV%qQ^%NZAp>{00?rCzct0w_UP_2_HkVxoG#0V)Z2<5@s*6jXVN}{b=tBUdw8h z*sxZPVuTy~CM#@oh@m$0(ZwYTjVvtIsxvcHpHmNwr`U8K-`qG`pF$oDn=+T0Y3E}< zTeTt9$~}k}JpZ9{DaPtTir#rsiaPqRZByoA6UFvTZ4EW6`CcmRsi4G7nfp@W&3?Jl zOP?yIcsOCa8d*r#L#J(vO9Re(l%f{Nzjqz4Pf?jG5IKk9G2R*N=hyRU;bzkX zdxDu8o?!ag{v9l%+$y#3eiKC==hoFgo*9O3qWCylIfmGC?0*@1u2o#v`uDNtx(bs4 zw<-UTVKxkZJAY=*82da9V8bu@V z+@?%|W_?OvZV`EGA`jkE?U7q0D2^g{%8_axw{6LM-}Fa@j#sQtsDD76fECd#OOMuT z;)|VQ^bA_Te%BZ7vrzNLOJz8Rw8QyG=}`&JeG_}RF-Yl-&=_tb7*q6Qim8V^An+Ah zj1f6*kCH~<54(R-eM*q|!}~)2M?nAKrjvF#?#CWGK_2t-x=(>wM;e$LKDWM?;r}fD z(ik{_UrKY%qw7=)jT27=swVvqUmx2&D+xJ#bMlQ%f%|W+nQMXGP-$ktI>c4|9hTdd z&!-{Y;ip;mk6;-qth9_U`wJtSx#|AGaOcziCFbG0b5A5anOL8)FXbJ0DQ`4PO~iiT zP!>w(TErORl>X(&h$AGogz?U5rBK)$Y7SJ5J~c7%_K59E>6%+;?ppb-A*p@5?u@iM z(Y84=)cmgLeO2fwrGp`wTx@q1{+2B|X;Wr>O3&PQ^Mul*@|5Yhw*&EAmBP0zpV&Xd{?EC4G4jG1X9y@rffj$V7q-zthsdOh#Ao)Zh3v*@ zb_3>3gXy516COciRyE>T7UJmNn2Dor<6b*aVgM+yM>~dumu_%VVuBFYl!5xav?gG* z$2MNK6J=flU7h$&!;;H1%&9>PDikwlY$J*e@nwkKD9*o{_s%UUc@aJzJ1nn7bhgew z?NiGPi5K;7^CI@(2wn*s6pB;>yn2I=YLU@#Yy|Fn(~^bbQj2%#a)ZOB1jpLDJ@Q%G5RK`F9uCViwKZN%yK|W*;uauA(#9N5;cM_f7G|}wx=l(AUo?x=?NZXt z;z>4RVjNbj6*o`3$W|L5Ax(A0AztRTsLzo@8nMKMV=mCp%uq++z?vLMQdzdg4S*&X%Onvf%B9yHmJz`*{j$bye6mpWbhW2`{v4yqAM?IO+JK_y# zOj8iA+*9b=Tx91WHrZa(d~mAo9ng3U(KWS-2duw1b1f{yY1H2Ie}S#)ihgoV?agg3 z?S$^fXgAD-6wBF@BBTg72gJ`HhBMIiO*uQ9eP5Md^lu@r&!!XUe3)l10Xs&vSz;JY^_X z^U9nAtG^jp2f@o8AFFq zG`$a76UTdn>JX{FQ&XtfTF&|t)B{yrPYnl#R!DP2cx8O${jf6fTo|t)>?v61q50uK z>Q7%ehMqTQi-l_8wVA+&ntuST?E|eX0j<^8{UvPwRl?=A=VhuXwX^;{&i{aB zUUhDfXohC5uD5&Cfo48!`0q6HvGX>~Z2nq<{5di|B>GS^aW{W)>Q)t%bm0+abkI0! z5RX_pkQ)M2y-&pxX1Jj%$5|{gdm+N&DC-9Xz8%7M&la%~jKd+5Duw4;LSdH-RQa9K zgZs#B#G8+lH{F-Qb>|L{Rf<&diO#I)*4@*sU;>D3=Lm z8zRh@mB3q1tNZ;R)9`1Y;epm#%s$=EzgQldxXmrKRFqaqu(*9!04Te(_R^wg8*-gg z*QT4(dj(!X9+2N(VBxj4U+t9=XNOcH#m71XO#I2(kvD{v_fJyamdx~L@0@Livq2O^ z{>$@9Ky_iOa@}EfY`_h66=F-hXMaHAAZ@bUc{_az;i`XopW7g=;}e9(oc|41Rl=m! z+qmjH2Ht?O1LYl*Hl8lyY;FPJtg{2o_5jWXpPB|dqZrJEX6!gPgwYv`$e=Sxmf@@{ zJl(p+FvH4)+#xRxzAZ1##@xBa^n12X1`H;g@mp)XRVh4+3^@OpA*^N? zw6s6PKd*(rdvO{+g8#kzPx0Kf4D-Xi9yEp;GfZso@3v2CJ()B+zYVAg!HqG{2m4zs z2?MQIf%oRdAb0FwE9l>6J?>O(srB|`;i|Jr>>&%NA$u{ki#=Xz{uE2DaT`2qRV>3K zw?`vfo3__ZJ^sdu{<7nC%2$89M&sn(ICAbVRwwA44b4?{Jzr(_MQ#VxM)nTt$Gy`k z7E0L!Ngq3ZRr`8boubRw(<)dr+I#4MSGMjqeA!+)Z z_zus9^HJcJ^U^VojMI)Qf&^A;rDwdQIa}Ls3A5&>$RVOM|Exay!=GYSqtbjw#&tzrT9btz-2F#+T{a^{gSJoAvoz!!GaEFwRWcRV;J_Pw=mxQ)4E8LKayv zKfSr}`4>_;5kOILtyKgnz(41mifV3x7CEnNd{Y z!P}f#%ctT!?v18p0XC%oM9!qD3?(B&RVA4?YkqP`{|Es zz0@pn(zV5&Z*Irk0YXT67^|R&z z$cm3!+0Emxe8gDf=(BM~WO0TbzN+y?mT$UN7}t6ui(40!F~PVhb(Q&uQ@3(n;G}CG z`Akh^5#QNP+NnP*d|S<7XTOqff9{k%3-KLx)~eOp`Q5(WwZ&Yj!AF?eSf3TvYn{1Q zdS0Ni*1}f%`Uo@7epJRPbNBRlfsY_7(nmf&*ryp&4fO7(aBY=2FOcq=+E`)NqMgV2 zOJw`kZ-D%E1khS()&^R9qe|B!BhpGh#}{iLPFv2nqge{G?`I*1d$ciKVLFMmtF@_t z=}(*1n-D)esb^}SsqLP1=BLewIrE~zv_3r`ePilc_Z?&b${9y8po;$@3;SI%mhlhp z+vddAKj7nA8YF1Dbh1Vwn(`M{J(hMZpNJatQNxy{&`5P8jcJA5uHQ5M$fEnN*@;dq z{O4I3b7#K4S>v$0bP5p&9!cnaCIV3-ks&^Ex#0=xOwipp>p)lwM6CNhW;^YCI`*`a zlm@ikHqd ze~i8QyL=~I``jxT<9w(|!|V5}jUoI5X>>O?;0@T9p#_hocWG+9l%JXq7k+X?-`S~h zOK0rJd7GmZHaCqg#d}lPP4)`1+)k~LWXG?i(Kv2DoJARPmdyz${XGLQrqzDd&o79yUba&UUP;ytx`o$?2+VhD z$HfP!tiNT+er#Adu13^5SDig^yM`Ujrik~Q_>9s{#MMms#(HU{^gK~-9te&`nti}H zE|>|5rt5a(O>%Yooz?iF4H}!3psE<_Aj~Dpv0l0ed6}MGdFHB0)i01mdYs?tE6*0) zB1fKkr+m!*+U)7@R*c&J1NPhe-i!40@DslyCq@`$LD3Jfa$_#o6@9&Gi+v{Zurl_7 z)vxc&ga+Hgy|__cu$ig!Tba(d8Ce{B;W_z}Emj(>|BtqJfs3Nt|Ho%`cG(41SP&H! z)MeKT2r2>=spYZ^qkx5%^5CT$Ky4PZP`j9Vasew-E0r!>x|nqFq(?!sBc}{Z>)3q< zut2m>%N4L16lLYMzxOk{koK+f{r_LD-%nr9?lAkzGtcGoe4fw!LxWeLr2SpLw_0CE zNtb&?#~hqfTB**77JY6DB~N|iAQmL<=f2p3d01I$Ra7F+9Oy$O_mbLJUx!%di*iYS zg2W3e&*w7jo4lCz&8lLnv)UTvfa;o0@x*xn}-#d(|bPm!b(!> zSH~v<&yl|`I!Nn)2Sl1J?P{((zf#2k9_C-j-A?ueqp1v0`)fGMa&Q zNB3UHJx}%n;+K;>OmYt#U#UZjbuCQb7K?Wy=`((r)FhBK53pZYskep;Csl*$i><|c z26lKt^+KL9gu~kpI{M7hd^oQ=nvqk?cK{zK1b1tqDmX`7uaSP~xv-KlmS!Dq(HM0{ z7YGC!82M6UHY(p+k7&Q37-xxa9%OQ8KzwP;-y(W9>_g+syuYd6LS|_-BCCI(%kbCvD z+^Z!wK9}V)4RWtISG^-x9^q>_M*b;_dv5RNH&;_aNtQnAu6dia*`{8eu5g7M#=v9opjjTrysnvnK*k9}N zStByO_~LA8U1{T{hYm(Yw@t{2M@>8@%J?sTPdlDYyc z!>dtFdW#BYcd;Rm_FWHkKXH6z4B$X76jl@?!lPFsp3`o&D65rI^t_KjOPichJ{bGZ;JKe6 zkbA{hVfeKabXxyAm|TJ@d@CsvlU<&(sPe)}qY#`Us>ojN?E3$<*JDzt$Qa0g^A3Od z(9^PG$pT?9g zTO(Y{nw%ZSUlrmqFRZ*j`?YLeX>_lmjE)Kym8JB!AtGINHT%NKYfGc!CO_D?atOC( z*`WuSvbg2mrr2c%m#%*BD)Pk_>*^f-(m(pNX>*L)6s;#7L9p~ypHJFsWK8oNxN{u2 zpcX>rNOTp`@cqS7CAAG@Kgto5bts!qB+S&a700qirg-gqf<4>fmsOCZEBz!ZEY+M7 z@YGs<(kN@MvbUL6sL z_|ud$I3OTkurfeN8+-@y)AZ+4SBWH>y28+otaZO(MCQH~|8n=W{!KNd!?n9#`I*1> z%fjnQ3;3{9O89U63Lk!Jud;=|>Xr6??bWqj_!NEMnM3qz9j+N6BR8U|uEiTR92!uO z{g5pk-h?<@&sHc89Ld?hr?=Yt&VWzzYga3bl3MZ4HpQT?oWVNfdz@9#=0|^p2rWZW zh9HyPmW)85OV;v{`3;okcRuD<+pd)7SKY2rQ9Gv$r(dd=;hx8}0u@?^+)>?vTeGDQ zgKj^{Nk{#q*U;ZC$Ro*`Ke9_roy0XGlqs20HsUeYls7{q%Rjtt;=9Os_zuSPWv&Ey zQQAF)6^#TMxZq3I7Y(Q#2%VZ$Mfgwy0uT4*vf3@9Q9|BQi|T zgqN$_lD4ls(jrJ0Aa8fSk7xnT;7r;B`OhF$(Ip=^7|@pA4sd7w1LNqI z{6ug`(!GBvVPK@W0}_U%m|r66VZf^n;*!#dK5HX8lnYUY)tiZYb-HZ@k?FYQz2247 zxS5dZ#Ji=5KMmLLdXi=aL;KnRP6V_4_9<($2fMx zlmYyB^XPCo##{Qln^|kB9F1ItNo&_cb%>)U%(EwjPQdAOvW3bnWg$I5gddG&!dkz| z9o#tw$<>)I?bJFuKkHS-bV7m%Zq~R6vNlMJw+|n_$Z{V$+>Duwi{z*xqsdSDpw9~t zfydZ2@i_YzDce5xrkXYJ-?vbKZJn1|)(H$ZmYbEVV>`eX7vDQ1H4;+ab*#Uny+LxR zkvzf35}ZXLD=g6l=_+Z&&!t>#oxk45MUVH0iZaDy{cy$35kd@f8Yb9szKMOOJ>=f2 z3Va7c7qoDRlKKHME1FYyGJ^3g{W0W5KdeeqA!Bb@22-gys)QA;tMeBZRsBsR<`{ZH z=>a96&<%&sNZLDR6GH`XnyjR?;(?Q1T(HHC|T7u}~4x?bcq6iPLoE94#3cNLAgaW!~I_511MLz@F zxjLVBF=dAx4B-7)m(f}-FeSB^pO{zG)cq+B082`T@0aPGH!HSe5Pg!83lv7mu;bQ& z7Tfl&Q2c|8M#b%^@+xCG@{$f+qtgAwvn|@J`N)7BBh0RZ&9LANOo%?L&5NP$pr>ZCQ_Xjnw<3?WN-@2u zgnTo5s-Fq*J-vDaZOUS&nEj+87oqu@GqtZj6SCi)C6o){E0?b<(@)WVt{0w)NP8C}GQ7b6cBqYJ( z#l*kiaCO%AEp@CJk&XU*t`BDYq&>aOR`SNra2~Jis)x*!oFntgVB=V-rcR?w!@c+M zy(nd|ye5m}H7UPoO~MD(WL53n6-v*FL{w=8R%E1|a4x}T?;e=jS$~+>6xau>LtaX~ z5bl}T^`Z&$%F6S4(E%DIuoCNtHDunGS9MOSLQ7T^Fo(FT-`K}uwyG=#6Zg5-T-G!G zOa3HsZz}4jy&Ty#s3O{==cuuu7asJJ&h`)tP+_NDLi;8%gAp!rMXZktEQ9O;*ztbS z(BA(2gxNHeU=}C!ZE?i1lMrp5XhffPUF7RA&j;nV9l|Ht2+v%04%vUAxH#6hY$!`b zVx4XqbT&YqfgV7Y|G*6N$guTyhZeu}#I|E44k34+`G9*ZJ}FUC&!gB-&hJ-Ki}Ag! z81~vIc_@tV#xLIM3GJKIp_`WkoviJbp!Ez-OGkPL4k*vo9VPK@U7mk`U4Pe~*3U!B zL%4zpJuG(AWnQmCtI%^HH@$UnSeZJxbyniE`azPT54dD}e3MB?yrNaanu&hcChLa> zCqe(JI0$`ZkQj1{3})1TW_Z#cG{Y)zkF>O)2j@8`Yaf|lV5ux{c;ErD*L*Dj^nkvktip~^$;@CzVoadCT$2cv z!fCxkFZYV*M2U3hKnB4rhFYACMxy`1i3|v@!5D%6}!l1!4OXgnh8IV6^Wd`=pgR~`X@Hl?92W)sw4MvW^`pHquf-Dy>G2lExG=N- zH(I*UOHBx_o(z8r1LwxKCt8$o<(ag!xZAVGWC@SuiZ;H_~ooxbE4x%HtyrV>( zp*edTygm~+7gFDG(p|kO?rn#?MTx&%ozJ*b-0OgZ?4G@j(=W+#JJ?rvt>q%1NTPzrFU#z0eDq!9}cewYQ>ZeHWXj((09aH+$II+*z-$=;|Lj+Ih4DuF!XXl1T zha+mRG|9Cov^h*Iopst!i+Il%aq6~qZu$kI)>2Mo4T;c1;)|TNy#N~z7PQRl+*;?f zX5Z$Cxcj!vd}Y6FN|eUFB+3i1`swMpl`+o2hCuair;OYKh-?l2;;BI#`GtyV7q!q{ zk^Ih@GoQCJ3IjJWTq7O)^?Vq7{FTV(lUM9i#4M_MEX{(Q(wGYmfT;nVHb{QzM2^|x zBV9vI23XNag^10omPU0e!5N#S{WdS~#%AedTiePrSz*}=gb==EWrGl$IV*cx_KlTo zE2Aed?bEy<52W@lV_yFuTlM;aWyf2FhkJ*QSgyxa;Ha<%8<&5I*cn~RlO4*j?zPoz z2z1PnY+B5)<8m&0b(oTsXyv|VPFz*9PdV>0v$#8}1NMpXFXo$mxqYC%;-DTAr{_pcS9}*18 zPcycIJAN^O?jp%rKzq*wh4EIOoYzVB;3+XM&3q*(Ffb)>px*0!6ZXQt z0kY!;l+EwC&!R5K!}WhtQdzjy^)7t;QTpzMJOO1L%3A#W9llSZOhF+sdxDFHx%G{= z?A|4?Wm)9qQ-7<}%&#_A#xcOV;Y15SON&14-{CL!{*3*-1~yiY?I7o#bhsFt>lrUt zVz!srlw1bv!=1KzISy(#(# zbP-*}IqRdLnLMG}PqZika83k-XIg8GIR@@f?p%HGjNQm@6L=PM$0P;2n|E`Ig!WL{ zj|ZEUCAKxM%3PK$1g|A0lnI&DT{31R*i;Kk03G9|3CaCm9Q`9WDngTgw}_MH@9cum zO1wL%wuwADNe7wx4hNqzvr^eUU9sJwu&bq6Hz3!9uF3=pR$3a1^>okj#*SGBiV?YZ zW5@jmNXv9MnH|`!^55EH?@ki_&bsZ3Hp{&GQ&`hyZ=AF4a3l)-{h*N}DUm;7AB!1z zzyaI7zSYE9AlB9S2(cZAecwUtR3Ii0RXWW<#xW$-#A79=dxw*AykvHfW2(o-BQW*I zAM~&W&LS=OOHN;b*g?PRVLyXB`aQ_fV?YxVo`3&#&|D}NUrmjvG=Tx;A)i z-VAbnyE=E>;HvRY75N?C{Hmb1G$RW~{vPd|@$$n9`l z-v6cUZ_eK(^b7F}vHekU!RmGOgE*r#L=|06jk_Ow#1E?MdPB~3i%<1=>zl}woyni$ zlb|69=Lvnf8|SOaKt&oeN1heJhT2UzMbNF!3(L+N0=;61T3`QmJECuQ69LMI(pUd8^xOLWbA~J7WA1vZ<+J4pak8VZsaYTZlFC|D2J{I>nn5Ggfmb82vSx098>=1|{4yunYaD$ZNq5eoDbmh{&1Ylhf&$~!{eQE2;E31;US>CIv~R#Z*}kNs~9^pDd|JFADzLYM&L6jejWR^EY+Uy2K>Hd zx%Na@lu**``Sun@@urY%-E8r$-rdId;!N`Wuxo2~dh4RlQcI2WZ<|R7MGlS+Y>*V- z33Wa_kwn&4OdKix=&UIuQU)ihJ)LdKe za4w*XYh%2C>!pjXZ~?f?L@=19ns8EK_GZCec~TWzU+)a7*(L01(^3c9D8KBs=DbIf zA8Vs1aC!#H@DlJeO+AJji{R}MIT+c<@_%&36b492%E{&+mV-Kcp8i=q)2dP&Zc})B zA#V2aHpb`MVJXSzweImYAN7&yd=7ESsE@0OrOOu_k#g9i)O>0z^$P4!vGP767>?OF zt!Y84k7A@9&*c#d4EI>s{Oa6P?ws{QV#OsIbLQ#|oU-W1j8BHmOjdKN+kEJnE7xqw zGN$Bsu%(SwFgs1ln6m6;7pz3q!XPG67Hwto^A(@bV25(#C~(T>#H%jSfAm{(MDFh|HtH3(rOvHV8Li!j-9p+X*q_kdl&Kt_ zg!0~$y3s=om^^&9S-NZ+O{mcq$d2f@-no^({m8y3#M0*F1<&aTvzn-}!yV0nd@>-i zBW?GRro%?~_me^IBqJqnbJP6iF8;?#O-!&e0`}!tro(pM@vBtaE7;4>-N?Lpihao~ z8ZVplitVrLh!JJw0I<#NWNa>2ojBIkge1btnTp(gn!APiz8}0o5PgLEU9#FD$`*73 z*2>F0yPYyduAode^L+KmVM0R0A$_Z-}+rVJ=Ew;=Wm?(@&W zZhf#4$=d`d}CQsl_0|%aX4QKc>YRW%_oB+gr zwS>(F}ahi4H4f31}lDfNrzh&9t(MvkBRvM1@SfpMEzMY4?xM3qk zpB=!xu?egrRLC6GrtuFEn?v0e<54+!{fn03YTpoT!|Rp{wXj1P z?h|=KEDK#2mMo4X{D|gfSnGa=>+m$#r3_f2PO7bwsYYV)k`y-9eyT-1>2v+YNM*yj z@E~!wp1@u2T;lpy8?EsbsfkzZUf8n{+!SEE`F%B^2KFPz5%_DNmyjtu*JDn;t@@|X z>3S;UQtbf;HSwSJy$*V3U+0P*y7VMCC|dIp*1F;;*bi7S3rR}OA5aUsov4+tRHXdx zgvY?B9UQF4v0sO*)E~CoQ%j9c5KXXCOsxOe`rM)LoRrW?%dCctkx`8?=v#nmwI0wM z^D~c(CfKd?ePnk6kKOln=Dgan+&g4BIu)^i(BQFZ_BQ?R@;^5XZfR>?orM_gpTdGi z)?XFIa;F>#u+VMkJn~DnFeBu#&?rQ*Bz-t~ir{+xp8nod)Fp7SsP`7?nIS{W=Ffs2 zqNL}0=$O|;Socuw7R_#o+=F)uL4)_>T_^~8^JS_T`yc*ZR4nOn8Ek&2h_}y}1ky$j zH~|AV0k>@eaDE|G?T0xW-{Qm!4h1aJFKy&1 z8T-qO5Hhyy-Tm$Dw_Ira%HflSmeg2-0sQP$8w4|ZcNJ9w6TzEuV;0Ky@gjZOlw;z zeS|=zzJBux3#=k1*{N~R-ocJ}B;>P2LU~mkKM!_Af97prI%7f<)>d(dT+>t;luA#< zGpMZ_UiT+HLrrH1Zcs=j#K-(je#bfZE-CoW!SjST8ypKEdtV9}FX27naqWXbp%A)G z%_(#3PHn|g70-fp@kIvBbo*q^gc#qU!b`Aq93tB~-pE-U`n_}1t~c9!G?wJRhCOXa zpEKSED`aV+#;p*KWR(kLq2>H2#I?HtJ(o&8`4#O;8D>W?JOF5uN_rpIX`!7irP`O` zS$g{&O}=d^+Kknle_0J~kS^PqY_`va6|FN{Cg7^6csDo*_dUkzQ7yN1?Y*h3Y z;wlVFQijB~x z(FfMCPu@cpC2&usJ;@UOpLiP9W%OHmP$oqYWaoX4r>(^*UeBl#Can#C*97s=dJVMZ zo3=IZwOh+7V_<(gks5ca|Abkpwyl87<}9C!&oJz5y>do-z3VP4-ZC{q`zrMK#XV6pV~y!uVQ@U5l2X8{$$Z!xQXQ zLBqr6&Q3+07A>elAiWWse7R^&rNf`%$x}3HREmkDM|dve!zroxxKHy%LI5(PeJq}L z5M9`x!~3DLH0)k091~Ha2;Lq=d@gkLr|^~s9Z{)dBosJ!cS|MW(LeR$3px|K_FYFf z{J91RZd+{<=hk|_-JewsWcBI06Q5Ci8Tfpx&*2y(`NBrRzt81b2f2723ZZ$(o?@X- z8Hb`p@j@|Tue}O6J(1aOgADm&=o04RnnT%)>o9z4QCjz@DLYCJ+G2!IFRDIo##hKq zm7iLG`3CcI&odRo$F(1(7+KJ8T)SHCV@*WC<6Q6d>$go|zqsy`XH5S3S3U4pu*nqIQUGKi!ytcZDAcK$S5Or@pnp4s?x_5gyVq~3%0H21av)=qU()nPBXVJr~e zJw4e{)z?v;L|KdSGGJ^SN+7P4C|&O%p9lUvjqk5e-a+{eZ3y_zKslDf zz;4}=vq?VX^Z8@Ki7ZC8NdJUS%(B30ovLPpPjYncCqXW^NjN6d;M`BjIgwQ$*E)_` zqz;kGg7-2NS^OIZ-@<8y*0#x%8#!TCRHF{o+K>Yx_F*3Mv=sgO zU8J+TLLoKhm=GJ}0xaXtXPx7-voc|o zs#!a%!IXQb@=e*2_wJs&s#|42(KpHJ=s3G9;mJE%4lCSNSlIIa>uBGHb-R1CwGK!N zWh+WzSG!+q#O$eE-#SjO`+W=(ZW_ZZ&lp&F41)&7@UyVlvMg&C=9G-0xH^-+^QIA8 z?#`oTjo(tvv;si)Y4Ejz)y9(LCtRd=l%+eWj8NeWQh69mlN+?3`SOG3+^!|V095l*o>T z0Za z{6WK@@qg2zu3f6%2b=3?j3A()r)qrYsY)~C+q1CRLG}jJd((3LraHfXZz4TU{jC8R zalJxJ>`8oIaBK`sARY|)Yer~7pgolPosWKxA-}`6mGHw#ZUou!d4r(S8p^q&989R4 z>RH`r>@T7@rp7m0gX|_rp_srLc}-=LI`|Z2A~_0)CS5(>2FLI;TeBrcf2Np9Io@vrFn<;UFeTjKYil16mZRI0dU$gEZHd?0Y>b&58a z+>kh*K%z>jK->h{K>ADWn}9oI_=DblNNS?AK9Mpdc8sS9O_jgGh6omc)*4tS)#{J) zBy&;{U&z*$WtDJ;qbhYFg+3%;6}^UO;~4PxPi|Hmyh` zGZ=sw48RQPf+`^$4R{kY?kCGXBJ!ZPe z85}>+fx0^1sG?-q6#6rXyn{%xEW&Zvwv<{Fjf~Ks3OuE|1v3T>cpos>JEj5e16Va^ zzdpDJJ_`!ukj>&Rh!U)1dpl2d(OZc%YJF0soI?e*J7$dJaIH^U z4@&V~C$pA;9c$r*`{Fe20PirNFu6-c60kP5(Q) z5maw9A}j>gqg?}`mx5^zVR3_{IvypVRPf zq1C;vHyy*|+JpzZ6Fw~Wx|TS`aL?i@-8IRfm16r=N-kGDd|z4(`$WjB_n^E38SP_`T?gU%;_EW)kwoC?**}A;hc~8@xEz0ks}K7I;A(rF zfIP+naP>O)rEmThxcWkds~>m*T?DEU?JMqHc@sp*d49AznFq6WZL4Q!Klq9h!qOPI!I$Uk#aYJZG=isd%a||Zl=Bw^o^R%Z5huC-EK79$ zOgOsx2p;qT9wc6hcfhi+r}HjIr%Tm}de~f#izD1kY>4vwa*f;4G+d#26!fZD4CAPwC`n@CU}#;b^L)bp7FdQ!*%gr!1Xq? zH>CGjN9X`t2LP5o?zs(Tc2DQ8h#>P0{{Enc0c@Ax9Mx@d!*oxfnp)H5mN}d(LvAFL z?I=G0j@RP*F_e>~YU&8eK9u(gpzm9ure@*!ORz8gH_FYvfIjuLs%-f7?H0~^JOTUt z0HIrO8HL{*#1D``PKD6i&?E-d?HDWW<19I(SLmJ;@5Y88zPQBYyVpU=Jy7Z*UamT&;|SB;{gG zxiAAB{muMX{zBF}d{)*M4%k#q+X_k!c?E9c_|NQxIZ2h1p#6}*_aol$>Wevi&IO0f zpp@#mZKi}uhK=RQvqo_6*~cs#aNw;JZMurJBY&gFw55B7-1o@3k-6=^NB*XPTY`nW z83p-nI@g@*UfYmlf#yJw&& z@g0D5-BH@~6`zKCl*D!uUdyo2tqajW7E5fYzeD*3MVA(UcLzYqSemg_j-XUt>F2={ z=rdwIXoi2;e@afoDe0kbBfBzPPmEPBT!Wp)mDpR-lD(-+z>pfVd(9k$9cV!EPob=Y#Rb`=F!P(Zb zPzE9sZP|sY3&MTLYuji#3pzVB3sOl3`(7M{&iH<2f)aQCxcU21kH)6N-{DJqXu=n$z0 zehD4plvFLs85F{|`*9<=_o_6=Y=ySpUfK&l6HQC{q2(92`t_^GJJZxz_zxw9(w%pQQQ{P{;ci*43m*;735chAn zciCMNf+>?*3)t8BJ}guyM)Y6 zV0weh3HoM;UhT0y>8+_g^ONT`5S*awBG55Qjv}kE$3j!;=-l(`O#D*T0|=>jugwdq zawNn{Qe2{O9$|d|FMXYJ`*8YNp`B*NW)e8ahK-arl>jR&Z@>cNv&iT`uF82+4#vmi zhWXl)VA-e2+rwpBcZ0**3~8Gm|1GsRvo<7jWzNGi?s%^?xU+~+Gwh# zO+m?VQ?QSUVUMREHb9f0t$*XJGhsV5afuk%VSA90p0(*ztLsZF)RnJc(W{7|$CkKT z@TtKrA#yZIdclV5&;Djch7#R+d^l!FNzPquT8i&1RA^YUvrn+J8S=O{^n4G4) z>;qgK>`mHMQCGLvs5W2b-|E?zrCt0zr$~GAG5@sx8rX{|b)+?4{jN6Jn`Er(Z*As4 zYe`LavlF=Y(Av+d@|sLmM3sg0mRomPVj0#j7<%#=VQ_u9aC5J3sCUQFh*aIk&#K;)(`;=5vORoPNk2}6-rx^0rZop0**EsB#@5E+!l9Bu zO#G;bW`hwFQQmfi@!m_+boLS?gs_Ss?UcbA#ug6$cvHG0X|HwWJ9XD=OIjOs?Y{mF zyE5iyy8?ckpe4I?M~{ql+s6~!^5?CUqqV0b8~uBG3*`1%hQHri<3xKXk)&VPrG|W?%ponb=!twrik`C`>6`5sK}{_rJ|PDW7FTh_O~^N zB387KO_!A3Q(*<5SU{DI9DdfR+@3BOd>`PBaCdVBPK~7m-nxd{G}mlvKe)E(;Su)x zoJxNx;+nmHn}NtLw)M(ppLUIp=JwOcZT8bnB}GMCxBm^H4r-C1C zvlq{3aZsgc+)k$^kUqqe(o>k7Cq%_-JFr925t-%fYg>7hRPf8&*XBP$jd}ap?T_Az zcj+pXl6Th_ejoBoQl*p$eTsGO6~$|4uli}&XA|B3)S1&{&+N6Z{35>De%z~;0{GxF zvgcxoeKNGKlwk_=t{SY|0c}U;TQ1t9ymBJ>K97z+S*95}P*M)G8E8JQ_d(1cYvGgZ)u}zWNMg)N9m6%94#8KN2Q~0J>)HY-xG@wKD{BF>*%z) z2)xubvKA3ES~L2=yOi)9{?Qrkd{vO9=p(BZzr^0%w6#^Ecy z*lT;t%?E7StE9YeO=OY2k`LnZc}s8f5dDI?tx0lQ+p5hL%0T#5?DXn4+YJmIMKxwQ zhJx}Vdzay~+^R~0kqQq+-m;p@49O)NNEt#N3xro0ZCv;mD79G|*k2s8-&0bbSUvkM zy9^oRr`kzGO6JLe3PqH^oy?Rb4s#VtqLh)jqoSgleo)_D@Al`T1saiS6|kWBQgg|k zC@B@>iLDleh-YBi8^Zl6Mha=_wo@yfq~OO%;@1;-?oTxJVuUoaFAe_84@LYU5{qaP zdSBkIp~(tDN=jPLQ4xc=PeotDNyGzS6!f@>VxdHPYA8K5NUsLtJ*svMMVW|=M?byz zqI&Ns>yreFlHCpe*=jocbDHd~j?Qg;WaY{lhsMN!qIktVM&9Q`ZcwApj#nIPqZA5e z9I`)0KPyHHmI8pMhT~(Py542gQ)1i-1Lt74oD92F8M7C6V+u;b=bq*bensf5}zdd z!Tsj4hrXeU5E+ya(3+}MGr~@u1&-VJ2IdcVZZ4u=agx}g4zB;ZITvp=a8G0OWJcWh zrK3|L&%?$BqE*?Wo>?vH^(3XL5!{A`qUHU9IVF-RdB2pZ8&CbQjf=fxF2DB7wErsi`;TyNdZ5n) z5;~A~hV=MbPmfh1crzIergyAAK+BMzbAC2bDf17774po>R!4iWL&n>c963h_gt*U= zPH`}U(Rd^$XH)D6m?RZfWNIQeM$s(y|7O6+B>mASd)k8yRag-^MQPatl3AW znRd!dCy-xXNAK~wnwm&@zfUv?yB)sVH|mYo1lY_|K7cz7JSu(B=a@LWYca5Q2$>0Q zLgCWj%s&sAT7~|@t5HGve~=n?342Wuu7`c%*G_7CgcLf^>n6ZmXr&u+?#8>o`6&`b zz~xB5C061FFp7KajKE%)UGz`hJNPY*ixfAjeNQED&tli~pVS?l5A_h}d9q=Zyral( zH}9w=@~_Da4~+?uV}Wk$@H>F)WxL2|eI(jvr{jwH#Hl-E?$$F#rpw-akurFCCBw2) zya~#`eKlEzaz8@<%n-L>t{nUS*ejF#-i_B!@9&4@Q~N^!%iW#t^||kKito!XF}>sD z{&4Ii+IaE`r6{rlRU`Is4DvOAQhPO7C1O40H<2D^1GBp8y_meQW8Z$0z!(XXJ%7>N z=GWqSM>Z@M-xcrR(;Z!5N(!fm|E_DV$~-t7F|r|n(09M>zqV}!V(l10>_$lSG7l+$ zOG_N< z@sr($3r9Ufh9GrD?yy`VZN`umsfbhd-yHj|z4{O++_-O?VX>%z9js$e17};O_=9r; zMW{tOBG3*zuNZ}ve4tf4O4^#Z+ugqy_s$LC_S-KzNG(>bbzc2m{h!q;LoL|%q|rti zzUn3XY1x)%H*{_N_ZDQi?>&F>Jx{%LxTi={;7JnQ61LKB|NdNvr_TJ}>txC@kAc74 zGLU%Eu5joYy)mG{JB4ZYRrrs4g7saxxf=0~7_ZcA)!tKS(>iujb(4mUtIH;B1mhVm z&vUlvidq`-oq0?1W?Wp|-=9+a1^q4lW`x;M-VLf$CTd%?GERe*Hdix}lNr1!Z-x^6 z?T?Yt-T6&Vph8In$yA+TQeDP8XL!u<%77Hgs5|@wJ8Ok^bD?F3Jw!-v9XySW-PTGo z+mhAx7cFZ00(HAx12}edHn`voKf_DDu63#8?{8c|6h%FazPzkgQV*aUM1kBV5fKgy zejHA7t*Sl7PsuGtu9n=Yz-FdhqgWukAt%7vM*Fi_EB=H<*tt8 zi((|Fx)Kdp8tpg789#jyw6bcArcJ5+Qb4>3`$EC5o%U-INaUy&*{zoAqGnQ+MG{Xr zXOFsS9Sp8s%UsPoBrxnDevPn(UBk!aWV3Nuame-?#~-qWu|8?ov(R>Mi}`9< zeif1vn)_J`GkA68XUbWJMYbP$H?(PUq6P+?$c39YBRofqNq~LS5_KTh?(;Qt4v!9`|Thp$w^hej^B2p zoJ3tppd)8&*kUNw%{ujm8e_mG(uSDOd@Hc+>=T@Jhwd{ekpdH6E^m{^);ie}6XAQGA zZSaoutY48Yr`r*@!+%G>jzQbMZW$7=FpLf#wljnCEA>JCIiC{R1l%awTmm-&3%L0T zvoto}r;IWTDgjI>Ax&2=%pJtN!})I4Zl5na;8dnl(X++3xUcy9U#P8V!pF&UyN=d& zGglLxnrXj^K4oJhwb!6xdMwi(uLWjGpsw{HQXu7bkPF@!@{)IRjdNGC-MJ@57o!Cn z=O>r4_t?)kH8Hqvt7#ecYmM`*X2OkSC%4$a0g{MelgGeUlQz9%8Olb$ru;?3*hE|j zE*tNr>2|TkxreW5iMY4Mxz9k2`^G+u{RUPGc&Bzd=iN-TYnTFo_`rwy7Pcy=A`5a+ zsIS_ytasi!3Vd>=77?d|N|ZYT*yz-t9W<<& z=~sND2m8hWwqCX5+Jj%E!y{5NV5bi|#(%71eWV3_LrRC18QCE_=dnYJj58N-YuPc< z_8UHU7aQ+Wq=#kHdbZRe*oT#!z8Hq|*e9{Uh&A;vY)^+NsVgY#L%-7+NnYxrjdm1S^4XL%I`lx$!Jm#K>A z9f4)K5=9Y(84O4rovVBaakt7w4n2BVv6aZm ze53%xLi}#1k{XJ!d;#4S`Tk(Jd)$ezPbJv;lZ+xuB)r%Zv1f!`7K8XAK8K5^`AX>9 zi+F9F!aBEd4t!!m#YC&ty2~<546_DR&dK!2)E(V!39UZfq70vxiO)ETHMn{(?z&Ht zy*=*J3+^+H-s(KIJZ$mkPLhuS@QbYb($Wz#>;B9CQ6nuX(P7UwRlfEAtLo>Ps^X@iGyn ze^SQHPiD$?^Wei27x*lG*__GtY1}gPRFM~s|VG|?cbRiKo;lx->vVo&e7 z&9_GVbgPdVmVBV})wEx|N%%=WoaF`7q>3#gA;ExmNVuzW0W5Lp@J44mWllaQ4r1pg z6P|Aw|G6{X{JD4*{Y~e}9A<71PTVBdUWa>T^q!d++QYcZ;>Ur z$v9y`1wFeKF)iX5>PmFtY)ILYoSKPSEerV@;$5j`!(C~_O9HyKRVDni)NpRF0r+0E zj=dkzMIY)-z#V_XI@VVbdT+z^Ao)70Hy+nP^7Z20SX^u6>-oJgxYo$mvwJ7t+FQO( z?TyBDfPBsNj>EN1zP_tB0@s1^bwckLT>Ht_vAyBks9C;-QK=hP^6qiH<<>=2;i>+f zo!akz;s^hen4^OXzS4!R;HuqL+O!+`%wW*8pi9?WbofYrlKUF%s|ng{xeROON;h`@jTggJGgsO ze{{~yf2v{~>tuIYU#9d`u-&wzci4u~><){fuF~>EgAX@rR+3~?!y-5C^L9!FyoBh1 zd%5>GgH_hw8VTh;iD2>AsgSB|@1u-~Va7})7XuA&FrwWu#z^SFyrmxzt9_<81{EXf>8;D)2;@>Bn zy6tWZFbOSw(?^XWZ#R;+$FHKM%I`_WRV1CR>0RYmMdty25)0;sjQDFIp>%PSs}HZ)TLkamWKBs z${6xXkr6(R7QCg+eLsMvd_aH=Y!-YOU`z1+5GD1~gKoNw#4hti-Zv$zdVTJ}Uba5T zTB^L|xgdGPNbHC}AS{IQDnw2~e7zuVf$q5f z9s6zhct@xZ#V$q+6t_oaaNJF8K;n4T?sPEi!IXzqA=1Re{+7#ZKRO%oADiW5H?R%P zu$c2JsHo+3dMe4RzTdWr^goA+&V_~8pS}M{F$?=fkTFISFh+390|KFjV7DT=tRM{&Mu0r+2@C&n?}Vj+j)u4bU(*=S5`He(1ovpod62Kyvrb=4*P#gUA%u z*Eym)%kiUg^Y%GmHxNa1mWIfFK$#NR57x^)XQh^Dc70l-bCzK}+hm=LH_qwa>KKYR zNk1EhrVRD)D1#-RuI~V=W|WVYsHxjfel1p0Cs4vrYL|h>!gmAg751R4L%9cK0`3#v zv1XLTz;iZyTOc2d7zDa25HkB~FYt}9jdykOh*3%*npdeUj`O<0CVI68E0dhF(%ff4 ziF_tx0#06qby%V8s+Gu6u4YoExU8W#wGY9UhgJkvAA=nHGw0G#Ue}(_3a*|T{F!q_ z{AW%fK8`KZUs(!yA~TP_2mE5X3`++y2{b|K7<0d{nEx|~GD`)v?l(UfK;r^%}I4l;-79WU^%&W{jjOsMqY79rZud1olr@k?W9O6b5kj=6!g zj#)4QumE}Jt*}sJnckt>|0`f1y{j6ZeK+34XG#}|tl+${4)|~N{ji(D8M6hxTY31- z!goB166K2*)zt3cN{aVYQn%@_zNrkSLnchnk9I2jCR_oTJ;66)&J2@h3iJLyyz+*K z0oV(=qgq7Ay6MR3Ge5!dKf@3D#zpk8oUaB3GCTC(3=8a%*CeF1i2+^4%IZZWUapFw;w(EPxZuFgB z1RFJf#2Lf2-E&?@hrbF-Oi#fHs5Nh73oCY6m^$<>hQyL^_i`vXGh@OL1IoxSXzl$j zlEL?~eGS8%icdu>SDew_QfM!s+=f6BGe?}5#!3qMQ)GM?kZp{lC*iC?#v!N3v`45) zb9PvK&O*-w3Al=Ak%mzd-B_eu49B>LT^!D+k>Tv`PsJ-2=I*c@Yy_TK@)DlHxiXZR z(Ek+aFNrZsW~AJ5ur?sA8KDQ~{MGtei+#{UFA#tFPc@DqtQTmbpcEDhvZz%`@O00D{X*-K~tQ@1y?0TM3QP9^OOJ&CI{ z{u{@8=<%jxiMR>2^wxaMNll8xqm4Kw?ZIIE%~EXs(KPRNodRAy zudIg$ZY;;aMkS~@%Bl;Yrv{^jDSt1{`eIx~=B=&UizqQ_=O{YL^vXxsX9c`{s6d58Pf!9Tq;*wk9H0JXoK8trw)A4Iz*y+-Z6a8 zcvb(b{A_d23h3eBRp8K-uMFkxMJ$mYooDh#p}$U0Dpbs?7XP}p04Zt7+mM%1kbbWXUVFNC+S@QD&>< zT-}nC`DstEUuJ{|>aqo9$T=7i4|293Kb^k&;$C9gSbJig=;VTR)FgxxE_c558?VPTw8Fx5ZBvr{Q$1-!F4>Yze8A1f^A+1 zPRcE)*lL+#9||8P6>JN(s}oMG6GZj&Q;;-hG~*&0A@hz;N*>*4!d?!6pTlipHY|sH zWEsQ=HcOU~ms(;WgXrrFaZQD7L^x~#psTa>b)IuoTqAl0ca#}VuF}MFKa-QQuk(j) zo&0^ed!gLQVD=45O`TT0XYclvzrX5!2Qq!4uV$o~mybEr^4(*wuU5ck?IDawf#QcU z1|a3zo^P#(^CVCMYf}3JjZV(Ym*5$TcL5=D7 z)nmJI`Yg$F<4o%9JbiQ==G6U{$r0?E8|DQ`k$lAlb zDiAOGP0KIhBze9fyGctLtWd*;&wMENMW$!)wgC<*PIS-AkjC!@X2u^j_=L8(wPzbU zA3PAl^>#kro8|bk-}PsL2HNOe#Dl>%@zu8hUN7RD9OH&tm>D}2UX03m%!8S21#OQWG?7 zUbLoK)vohV?g+5^PcUCuP*|rnx6dzBl;Jl8JynnMCcTiu1 z9(jix<MQYk}O(mv}ynzn1#T|2PNQ3*6^GU5mz4YN@`Sci=Mi zLy0wY1mgK!*_W??$0f0B8rq#0M)FS4zQk{0$$<@sf48kj)gD3JU;#V2zRqtUH=v}l zeC%1ekiO@=-Pvx0T zTK7z&rcJ?o2E9tU0f4$Gx^v2kh>s% z)m_&-56<0@|6vL;Q&3N^$ke#K!Ku}yz$1|__!oF?(aF}tIfv>plWkI6KGXKJ_9VRM z=t*asHbX(HF7~8TWBAHxqfDri=y*+*32H%kh6>_r%CNwZCA^ciQ~eHj?RD%TVXl>F z*D+CSMs-;zg^0{TBG|QqpVr&qB{i#xnbn zboLlNpT=)91sme;X5|BB8RDzGD4DtvQ*c`)`Fn30!%QVL<3j;GzSUnlgDQ>#^Tlz# zZHywUx-3MsvxHTYHbTqk&HQb|TuVAT%si5<;;4x=SC|6e)yi(R%&EmWZI1X=FEZizwx{XUVij_+XisgV>R#pO5 z2xg?!bqhhW8=66B-4^T4h!vC;E;zzuy+LHg8J6Gkya&|otIKGAdq3XmpKOZC9v zvrJGjaPbq?w?AHvRcxZ?ZL1B%Xz92-@4OhDM_2IUdBdfX=~`)a+?Quaf49ZQXDuRF z*87~!F2LAN%bS=^=g3-Pp_wfVf<}!>^8!}%%Dk~?%Z%lTuKu{Uh{>2E&&%2Em?i2N zk>B4oOFoxoNq_b5%X=M!;k3y{4m8M~4idY*?U8awuq(LIe`0P0TqZ+s>hcsuI9P1_ zaVcF@**6T4>)R5`GcJ2a_hSoPFZ4Hx%k=zPoDQAAnO-_!IC9E2xIr7VBfW;S1W7&v zwiloi%8-Q3h=qJF_*|qiq~%D%kse1{g5-j&T_JF51=4S`6hw>r&yg2m%}0PoSl?Dz zo{BMjq+`l}4FZ=qseNzx7QCbUPew|>X|D7Z_rt*(n_8cSF~xZ*#`K?_4fwJ|nwj~K z$I%g+n}V3g((F8e|9V($R^mRXBCThoZ)-fgRDO`kZij+)NS5ee@62D1abI~Evs9rM zk6Y$eRS8!vPZk(x-FG`x9lgEuc%vD0hUIRpVhfaFa0k2H5XlK)(!5q$N&NjbDwClQ z&{`j8q$|aStE|RPT*(#lBs|c&c1)Mq?Q=oBz;Cc?GDgMxUb21GZNHw_I3vxwqSs{k zn4dR#*EPIk`KT{vV6W?RKHi;v+xLSTPoR#qcHy>Xk&Re81U3dXrFhK436moa*e2cf zUe!p3&~;HIth_u*7DHdQs5OQn+U?gTK+9YmB)Ko|Bif z_+8Yfs5I@(-`(rd;F)~Xz}u+V4A%gu{%bhv({2Kfi@CZD>3bwIY}sZbr}MZkl9eH3 zB8NR4^Y%2-A*5|cMm$ria7K88BPSW0J%O%0gzMSRFVW(C4erCM8!tHJYz2SFyumtJ%TpM(>vR`FHbj zd)vzWsN@ULTB*kG^44L#{DjtSL5vj=Eh~y%4!>03jT8d1rywUj}cj7^-jmHt**-6r+C(dh5yjT9>NfXP44+ z70k!GmIALNgUN8ccrov!OW$zZ@GW+5BHokt52**l zypMhUfgZ4kyYu8NV?b4~0hwZ;DtUB}C*Tvt9niu%n1BUYs_NRj6;y^hwl6O3(P(o(TL@{o8`w!B&p5!-P|?av4uVDN?JU3z-tD+ZqWth$a#c_X&Vv^H>_X5B1kV*<xr`Kvz!@=6Iye(#$D}4UN|GcDf=zgKUVd$iTQIb;f9RuzFB5C`2WbWzK`F_w({k z&99lC1$<-ji9?3)YwL}eC#H`KpakTg8BKFd1*UPp_XhKkdm^h1(DXD=|MMg6bFmg` zm($03_#UjzfM?JbKL@mCuS!vY!!gz*y9StK4Rg_U9$qE&;_AF5DbCux8PJnacsbpf zwq!veoyI+mHaaY5W9AOX2hqld$S|*ba5wzEAxeccTJWx6nct>nUjB~Zij_vcCIPA_ z+9HZ!y!d5(oAteGBq?zVPEM~ZgHb9VJ05=D2vyKhh{xa(HxH<6Yyscr2+Z!N6&?60fs zOQaIIJkR+416X86?L@zS0E1Y>rC3*w++0_W-dtBRFVB;H(dd~g<>x(f(i9F$05f`x z@p*H->1UTko!1;Wa=VF%{?=uwVT*>KojI4^%|49P(7zn~7BE4LI5_{-x}Maw@E~2+ zG1ZxE{wwu^tJ^f?T~xbRwQ@k^Bj2fQdSQHUGgrpF_^+m=ij@Sk`G$~1NE&l^Bb~r z`+p*>p49vg0Si_-dvOt@gW40&_<$~oHVSilmt>jI%ZIHsrAitTQ(bb4a?A{r-05UG zzPx-{pt>tRH1?6;neL%Hbfp6T5jD&I>X?1LC?I`2?g@Ph)K&g?4cy z069EU6FpKG?#tJ~XJQ9O>eAr51NqC)=3*T(zh7L+$4^sUXY_jLM1h}N@xdXA=RkR{ zVBW+^_4^2tj{D71MP6~g$(4Bmvf1^Bfvr?49WVP-n}5KGm}SLt%@Jc>hi-|bA{J}u z!OOoXWzdrtc-iLSYa%6Vxi{})fh&GkXoGE%&(chDKk4b%ypOQbl-1zKYPhYwRxd7{ zwDc9M^5d3_1zUtUOZ^s{_2PVRXOr6Qey>jIjnCXaNcku3@1^{>Th;0x!b2LuHXxqi zW1kiv2Q* zX;~-#k}$2IlfS}N8X)k3c$Mmk{ZSOTUdiQ^S zKr>H*X7~Z?rA<3li|nqtZ8#2R^>U74s!@-{&0pj16<3A2g8ki0v}Y zoZsAU)FV3RuEq%y!>u+w25hp!P-V@1! zlvIOb|4WyaKu$U-cuCrl9%?g49N;NeMKAZ#BJ)z@=-u^g-|x@4MB(6fAd>V=NG8~B z!I21G6BLS2KoQQ}KXQj=)S?V=+R{v)rK0ps@7N2Yiz|N{v)F7TN?N9im(#{al z|D#9eny~9|Q{WZ!l#7@;orBz0FHM$uE9Zt@${)W$rJr5S15$jbNo_wLn1MMK}0vzfuS`kzwuJFusoe6M!|K5it{wbUJr-(GqA> zn5G*QZp$^2AQLj1XN5rW7d@-eTY8uCx~uoA?{CP2*;QoN85{Kv*#Y_2zp!g}I8VB( zdgPveti9=pIk|!`Ovv~t& z#5v#-brYs6r#cEcIsp1FxO3_&5kR53+lG%UhO~fqL}ALpNy5 zuO@350 zSw7a)Pxm6;7X!ZM7@Xvk!5gL|Tj@J$p9vVnG!$RFZhsK-8GYZKG-bFk1nu?Wl-paq zst3BAhP&%lD>7_>ack@Emf-qV78!AubvlKJ&oy2GL^}+3p1wOn4vSa`rmfe^87cFv zX%a+ZT%mwy&}juQ%ja~L?13kI)FBE_*$}+H+pcgBcnz4;KKEd%a6eAEe0@5d+ud>Y z>5xfLx$HpW$A-+h8 zhH+*~Bj^aOkub%Fu$`y2h=%4ob`;va%=CpT$+X%OfHH?lWj^as+M@*c{4VTpPUvPz zO6}A(sKYtDdn`^3=+lvSI@R6}SmK#cebf5g#3(CWeemp`qe9dA+c(wp3FtTs;;77;3a&2FAGP41CNwR=^ze5uK6UWT?UV%z#|OVB-Ki?20ES zC&HHliyrk2jN4J&-k;u;D)u>8->fsgxGvSm9lil+=!Xuh43$cOMek^qBDh1J5-$jOwqvs*&R}@ia zuo~HYhCAwgAdQ|G5g3<6=|rNa!^$%41jRle>`8OG!v72dEuW!Nu>RC!tB>TBz0+xO z(-ScD>E6{i8`c4|rgZ2rXoL{sN>idqIvsnC&W?Ls&4`^bxpkO9cGJ^`THM*aLXZ9j zzEoY|$js}&y@*FlrFGF&3UND5`>E9g(I}5Uz7p~kjQx}~@rN}!CVIt@Khs;5Ifn+(eUsGW;7mvwTl<)-R)|(ubA55Omkhd&qewANea>rwa-Hx zD~^!CeV{isNT8=gJ=hQ>(I{%cXT9aL*aB{95NW8!(QO(;va{Ygmb$K>4vMckoQpn$ z-{KXZV}V0IMIMH_=B}A}Sp7bU3Qga>fJ*wQSIZFW6`_?(G}VJsqXzh$Nu!o0Ym7St z!-5@#aMQr*6VRedU3$Wm%4aN~8vKh=T5U?`R>2k@rG~?1YsJ*8WSqI89uv|s)Hxq{ z64DEjK86fj7NS+;&s*a%lK5OJ8TRx~d6{&_lC}8pfe8voIJZ;-lk+6z*qn{kJ`;dl zDxU`Ba5{UJL0eC$5O*bL6k-J?gC3YnFWM|4&CIyG=Ds6q!1quJj@|^hEY?NoVa|>!0nG zSC3EAF5GiRjD?7<0Y#9`}n&bmQ{<^5>K?us7UHND5%g>VG$E|N*Pxd(7UC&Cnv6~D(Y%Kylj71sm zxV>exbW+VdD>(J_;AAO;#fnMSQx48iZ2pew<(4j;RY`3)D1;&U2y<=^27Rf+YbDXz zV=dvWE4X_R&L}C4oI3`(&`2uG7c26Y?}APt(rmm-K(29db1vv<_^A|gfDwer^&VNd*;q+%pHA8xn)hySkp+2 zxA*0)hKd%FNm^kmJ%EEm@HvYbQlE_$b<;ZksivSrvHQHql%K8e)@WtlvF)DxG=Gl4#C=_I}^Q@g`*p ztgWJlqaSp_Y7;$=2j@qC+rdxoxItT|KmSGT#dGwl-JQ=#azD+TkjW>( z{}$2`T#v&%rSrOE9Bf6AwvAPgGf2N-ZtE^!o?{Ld;=UaB;(3m|i~A2j>*EZ}N@)P# z%m*_vu=W!2A)k+cr!MUH@&d*0S?V)FT5A6cV7kYwvlQCzQhNH(Ygd(s^%&kT8PDpM z&8XTA%&`U35Q#c;os8HFOA|6Q4IWlIoY|hy_$I>q`*iPqdMEDaYME}RFifglp|}h5 zU~2sgmrSBi2U&-wff`hucZq2x2{#?Y-bQ!j z4(CH|ZY_!50-cYIH$aIbDAS&`QyrKNXO??1upUmqqC1>(-SDR${V{ONfkZDKF&p`G z>{Anv{)TiJxJCmzjIU@8I_qU57v-ZKOw3@S=Jx;FoS;>gE5RxA^6MWzMYMBgpteAL zm45?ba5t*~d$%*OTVsx`oT9jHjg=ti=l;mxKu>l%2X|{Fd({Z@9meJ6Wu|F|HUERY z@IcTD(~>-u%y_yJ$5-`5zt3HI5?br?7lhv2`Tt#an4EPT$7<4hoY^0FoDm&osorGk zi=%GoO{zt$B>QU9fj0#&$-{o+N7y!efpoNmBU!(2WGiT>0=F}VzSihj@n2n^g(JycZqWQuB^?TYDVUdot9?M@_2 zU5Wkt&++o}d81%kI9bBXwJxHSOElLXS1`G@HjfOadWqhBeTRgbZI&l6CUhSr;xl=- zVRd3&*aNjl|d=yTAoA2Ef& zX3pWK*aIEBSp)RV3Z}n4THkAX>^B9cPkFVGGY#{M8L&+zu$p`mQiuBvGSOqC=o`iO8#zO^O zI=l>I@qub1B=It@=5G=+H+!pLeS7plypgnc@eW=zyfp2kwtfeHvyYYL`EJ*(ejMSF z3m;bY(gSkP1NxTFEi_Vzx3^mUu#+8apwfreJLyi~og1;D7{i5BPotA4$#`UA%Q&K`<7X)m2DNBrmZfQ7f> zKZE|iL1~R$!*T9{xgUe|unYK@;^HpgW~vVmhI=!vlaL~R<%kvdq5{bc{Hr?4kslo# zp>Vw_!L`#$XMfb6@c0*;qkgA&iQ=wV(4~01E->!N`ix!*L&BUUYbxcVWx2+y;G^F# zWSyq?n)3CFz}GLb8gNIs`aa;H(}6cPF%sVF;h{rEX(%>&H2$&{Bkys(+wG<1*5j0$uA@$8lgAI&)DBi<50}2#*48>0lhtCaD+JGi48dt3H+SPNdwAyqqhNyoTarTL#Yh)0CT%}*V=PRCD_l-wM z^;Xz8(C>qKzCTgc$SAhDt!B6oOcdV7{G(|{AN*Q zUuv2;bp7Wm1~B%){tw zGD-4!Bcvc2l2Frn)IwtQ;y)}OVQ$P@L$TUR7W%y0a+p%NkMWYUfrT!gSK>eh6;aOY zuB*z!hbtt`>{Y|W(}}J=piRbEImaf&4_@Ak(TgDzb0#p!Ns=syAGfi&Z_<#se`3Z) zfzrZNRJrdURu#_?X0RU=t&j< zQo2^S(=VnMfzGM1ZO!P+iq9!Mwi$1z+>_GeM7;2q*gqx@=gC{CvUwabmz5XHqQvcc^arZ zobU?#xFL{w7BVO5m=?=q_yrpKIbv)amc}3tV-TgAVp`um`5;Ci5u=be-aagc4BLY< z&?w+vWf!IVJDttoC^IXm#G(hLnO=!S82HKeZ3VDp^X}*mS?PZ6s}DB6ZWv*U%kixu zBZ_V4e|Ddp(o7!b)14Ia_`1mOV%rlvl-~q9I1SYHu;gcUeOvUwDAZXYamSO|79FHJ zGki)Z*SDn~oU5R1Pp$q$IC&-%*hIc6G%d6Tn*@rxx+vb?G8BIEkfvizP`l2y5r|oZ zMDc$<^1(>ck-`^1PaJ#1PS}`OhapB4X!1jLj)Z;>Is9eN;nL3YIyeEhb5ZvXz?p96 zd)*W4k4W@WuJO5w<E%C(J=_R+C5Iu(ht#lp*_-)B!`XztTm`_P}tF>d{j;SEGS2} z|I}uFAKK4%G+aU+Ze3u8#E#i(aMmLX8FWpP^~Hwt+C^c-hPzI45nqPCkkWj5te(dn z^O)-rwaW8*-*Cz1Evu@<68No+DV3EJA$mHA9%yAtm|{b-pC8dqY4+pTB06vWD8(9f z7XI=fU1C7#P-#L5&aAT!vc+EA0S>(q1e)hZdw)pwRvE(5`rjPk%1$biU17K-lMNLA z-pLfZorPWZ+dG`wUE}TauDO4!&==U`r5EguqjQpV1VO9t7>=ZIE(qLaK$Gm0wRJ>;S}V z^{2WR8#I`=GY~C`=G}-H)Zvu74%_A8FR)dQd;n`8#;Yqy&=+Q0ho$#NB&M}SUf6;- zfDAmu_(@Sqx}BT5+0sQOu5`DFFTH4zl}0a+mo8eMC`Ei_cJ~6`(v#4K_DlBxM9lVv z1yQEk;bCF#ph6TPxk&v<1ozbWeYAqiO`n$vePGBU=SeGT<{HpL(x@#Y9y#-x0DAXUw4Q00SEMKwejiiO-zOc6 z_O>1ecJ$J@kJ!?HdpyoZJfvh6{HMg4<>K!iZs%Qy1(Ybnn%5e~80F$+&pB6Y1)}!h z{XCpU*5TP%kJpN^M}`~h9i_=r?m373dM@WXjPK45`Y9IE>OACMIU+O}_V!m}1OXjgWlY<9x5{lzsXzNH1cV>IP0CH1ZNU$?{_Y%=f}bpO5=Wp_J|bsNApYtLfqMR5Ex6oz~2$z+=Ovidwy@V2uiDlQ&k4mCnFl z>x8#bjbEikNHn?7>QRz^0y*m2TIGv1sgg>~s8ps>d0Lcswv*0XKM&EU@pS~Ex>5gd z6RMx7L(7LhGIhea!CWw_ZnisjBO6rm!J&x>< z30o_vcmE5{lUGE$&mX85dggKvr^1#+_{}1sxoC$sKg%_HTogT*W<5-MAHf&VmxEQ5 zk|slgVEc5~pgKKBxYwoh+hbs?UCvj!bSUMDr-4SRk~5kW$92N*&KF#JpaXXMce%8l zg@a5BCG9kM#w|;N6~}uZnB@Xqe^*26rnXr56@3MbINqbLWCZ_InKs8rC0i@>fui%M zZ<F>XBvvvwmRG~YAKmn{332wS+aX`BK;K5g^MW^bmjvmDHL>cv29{VFc+JcULkStj)u=D< z;*9IV2?^(Ff-a0f9*K7i%&;b3yr=I>WadQ;aV;cMbF#?{^w}hcq3@gtP+5 zg4CdCY+#OG$sbX1p3$xB!{}EIVrpg#Vss{4n{cfk6aGwoe&=^OE?<_)&(l+0L_BF_cHT_R*w)7d< z#9b;oPurbCMm8n<`to_z$+Gitr?#B;eY@;@?12}~D>s&%AF^fhdBx*p=LfHQ?!0_) z+4(`spFJ;|U3NZZ{-*Q1vFv>Gw2kM*do@i>=(h&h@hi0NWPpX1E%jN={0q@2o3{T( zclTGEI`6{q?(XLQ6`WUYgYydD`~q-(0XX*n&OLy0GvM3|ICB7J4&XEcPBY-l0-RZZ zGZk>A{so*@Zi5qL_ri(!b)o2g3+J!5!FdUAo&uaF0p|h0`8MF(0ysAU&UJwEalpA8 za4rU%^8x2$UvGmGW%t6#0M4a=ljzFMD>1(@U&nDIED^{cb?_i1X?r8j*u% zIcDOQhX_0H}@mKO*j0GxYRX_>^{Qp?g>B zA$NYO%5j>gj~BUjU!%6M#8Hbo#2M-N+XcDNim9ZU`YfY~&GE}&K!uhVT5OLr@hR{- z$U}$y;m6=(F0tW&noUzq$R3K~sLR?x-4e6#G;gJ*OSw=3Ag6`*5_Izs8B(gn{mC=M_E$ z5eCrKn4^%MNZ$?a`A+NRTiO5kE>z?KC)m^?$H&^HyOi-WT*~oY2sjC@2dXHoJp;Vn z?N7IjcwB#sw?xm%x+`QCZw5Ptb)0)GrZ#j5|es@WM+T!Kb zz|$}0Jm}ulb}3wLi?93|*N1RTY!Ou&;Q^OAW5raag=grurxf0D`SH{0Voqzt^+pQk zw&svQv{!v?4^;v7@f(|2{(T4cSOD6{$2;us;2Axq;ZAXV$_$$_hxS@c3qh}CHU}?6 zUve1@Y;$C9NhyC)Ql{!wNmG&<`ZPzTB-s2m`gA-$fKDS4fAJjN&M%~W{0n8UAPc@ zl&fmmi-jr4hjfU)PFBFT$5y3- zV?J$Rh`eZK_`Gm_tD@j-oOUP+Wm|oUlnqBg?NY1CT~@!@jMPm%784(sW})37?_4lBOyze7OzKAR2g zR%Pi9BjwUAzzTAs1y*Eb4;m}&n+(3y>-#fzGJ{6gA4uuFPPO~sYrCCjCZSKXX*(G*qjzuD;z5H#E$ATqtc-wee0Q0 z_Ah#bMUVVc$CdKMH^O!ZX+|b7(8>yY0}GG55#datlJ-aw`f=>elr}3JoeH~;LqWFK z&p|7Fg$&!qKjx)jB*euXi>D^RU zjrw*fhIKL-y53rh6EVukKaVGzj>^rpTc}>;waz?2-$tOV8iUyMG9fR;Tt|5jdSB!s zu?wwL*DdP_v_Ri+_{f-pOZsObt_F#MZ#a1Q>2{uRFvI-nVfm+>C7>+__c=~*KOJ(< zW=8FU=W8XTyO?u+Aucu{%q7$9c6^Gr{ajpG=WIlc@`Znrx&&i%PN<7X@V@iRf8S7C zP2#UvFNMEh_^l4IqI#v4t^nAVkr*+}WvYtnfp3bdxbj$w0%w%_VF$3c#m8^9@qNSh z^>V~Bf^UumF(ULH@Z_6%5)+#~q-W+#?%~<>kc&)_xOS2=x!HFziFH^*1bs6%MJoWF z!0lA37Ta#y4yy`SQYM|V{$wXPK0Ll%Fu9r4lGs`+HwE4i@ofaO^}S!0;Oi{|{%QTp z?w{`aZ#61x8G->m`g-ck+|?)(>){`wEyO#<9|kLkfb^$-pv&~2-})00m#kwiBO1JTrVT}q4b3vg~ zT~Lx)=YfpF^}ZFqZF#u@v?TE*mYfTFh8r4CjuGV;m3iKB7>g~Gmcv+1h3YLcFMw?u z$Eva}json&ui&cQl68TND7Z@ewp`_L&qi#yD#tyKdnNAWxc9}q689?H`{F(T_bS}$ zLC*%@USG520zwtWO(J0z!vRaOPI-Z=+0p?1p`o{L0{num2KcG)yC5XhRbS-3$d$;I z$mPi8$a&;EauzvD?@?xN-)w%Rr*AAhePcP*hqt_OiS`c}UvO2OQE*i=ui&aK8|}(P zTL3Q)Smp6}4p@C(%DQkb+E2!Bxk|rh(FX4~XuI?s+Kz9Pc%O>*zIgA8GE``z3hx8r z(RRF7XKaz`3dZ|jybs0uP`vMp_kHm`4DYit3a*CZeK_7n;(a9E55W5Yc(0kaMS@d{ z_gcJw*mZx)C3-_{lDl(6Y8Px)44$B0qr~4OPep;LHR+^b{+bi*XdfeApfiN%;>O|EjA6K zJB9p|riT6wd>__8(%G)=aiqm|-Jb>SF+{b|=W;sN@$3#3I0?`1Fd*-F2bZdG^f`St zNfS)Vxb$^bceu2c{uJrm_OJ*4#R7*+0RHP;>*Ih2HvkV#&;>P4(5V`ektZWhLY{F8JnrsHvbaYz3ab_09RnvVulUMP(zz;mw4Uo&RrB3~;hbd+K}) z>WD=h;*?Y86Htc^b+{ItI-i6(l2M2F_OItBpbkCipmdr`bLxCAT;k+YH{o(EICT>) zao4FHxC$CC0mn=AVDF)I)S)f3d@I@^zKwgdAr<@3Bu&@_iVI%s!T*Xl-#RMaV#Y12 zRlAt+FB)#x%D~mGnA-50Izr#dMAx+QTxK&DIqlcJec38SL+&@$B!x@xi~T{WNZsNRWoqn~x2< z%D?E98PYN|<9dIusMr2JJ1_S4{&};04f6||^1Jo;ul$SuQ>i(X^14r32us|oXw^f9 zGis~5OneKn59n@-N}OYW4?=5tcQo2obzIy}ki!HjthB|^O{MF4kh5L5Jc*Tz)23# zKtJBOBY{8V*%S*uNB!%Z6wwMgXd&<3lX2zdE6Mi@v)G8 zWWhv4!A)EFl07(MuJ)GBq`$~_^5XX$qvf!hm%&CJX)zK#C*JzIoP5Q@P6~Zq0XvMN zpF>~$Gl(gWFTwpY$lu5P$4KfU`4#gj71Pj`f2}jdm?1~klWiD37mKrh7OfWTTTyN- zY&xg};dw->|Dhr;UG*L_m<%!PkZ;wPpFxXvW${ac&G$-UnZ1CCj$aUM{-!D5VJa~= z2@l_dj+L$sUVox1SEJMj^NY=#pS%=aV9H4R->mXdpYnM4eIaF>Bah2Ak)Z@W$(8$= zA&6;M^bI0cD;vH_xx*IjVj^voOU=)RKdh~xw&deiDqayYfaOv`rb13P}aLfWWv-$4|Xfu}i+hA8eAs3oY)Yd3_DIKY& zZOkOR)A0>-rreL2l5LxsKBZ@F+}krZ9)#A_{gNbLI=n%~lyy1Hos7;GHmHiC?4>^C z@;CikX8S7l$qI|0>*2e9l#spPZvqpu0eAQA&o;#iRl>bOkx(MYN@fUOxyW?ApeRKf z3g@CF?6!)jG;*mdb~mJj3db&m!%E@y!plGx<%l&pW8Q6kIQ>Pphr-*ZP7(WeYd`56 zcy<)#6zt-u7UUatSpg9T+=w>Iw%=(F6kfIS;t@}uj3RBHo7R#3Vx1=><3(-AO)V{d z@n4?cj2Hee_dfRw;JkC~HRP>V<)oa2Kctf!c^oMpX)TftX~_wWn2`@aYQyz?$W=%J z62%A1paH^b6+#9N$*bzsl)C|86#NQ7KGjE(Pf54{E8M@3Bs^>#ml1TZ&pzerK82XC zuh3S}cm`o++0uB7+I(xVnKP#>ji^kLX4nIIS?Ty=jFzreRx95}ikQN1VGqRtY#dhp zoJeIs_zLA4S0j=tj~J%Z#R*iet-+~n8k8Q@GuC~2#(I=3R_H5X0{MP;pe<7FrI-%zL+ny);<}3`$NAbc>KI8{7wpYs*BTnZI^9()gAy`^@^Q{GhOlK zofwf{-MsjuI|2Qc!00B<#hLnwBYlNFcRyRv zC;e$7iQ)E>ZTo;*Wzu@&_sPZaofTCw0Uof_%+TWMktV-7)lE55Z?p`BO^!2lx!A8O zR`?ydC|3c^J8n|#i+U+u`MFz8R;N=eAQM)hf1a;cmHHj9Fnh2zD+g`LU4Xrcb2(3R z(X~$Em)g`(jHc81Qjb*eIm^DK<&PvnV-ja)zzhF?KgliU5x3E2o6u!k85u5+K_lXn zR2~?wtY+?{T2}cHBZYLMVifi>_B{vde}6h#zSd~X9wkhNw7EcFu><0JtcG?QGi+}C zFE0ICiWaq>qD4g|h(2y(zKcebppg~l3c04~(9b{8kqb|-BzBSQ2dO_s)L}w*R3A|SNOnY57>xMyW5vh&eYC#O&WM>{Rw)2a#7#;gMGL8B-%&f z%WXFMJ0{V-5gyj3HL&G|_7STq(YHfg?D%?neg(Z}%SQ=X+%LuGesE(K#*~h2DD0iq zL5Cu&OHOi5L6?3kbW(6#@(D-osgsjPg!W8zVWz70=1Vl^ugj%-~-!YRfy`H6fBQBNrd;xNc_#W5miDFj{RG zhgMfdhj$#7eZ`U2aE-X%OZ_smW~yrm32_{;sgIw=ER>6>9nt1mshlYt8gqxU2KI5$ zCVHlw@V%TAl3$$FACu}rk}OssS0C9%w8AgW4}a6ZlRv>Z5~H=^*F;?MF)`D-Px`@I z=*KjsBYjTkwK@1*D(ox}&rZu`eA16T%fvHkd!a^ay}E|aR>(B9Sxa$7CX+BVBi44o zs*6!kEg?pkuIO1Ey}iN!yQq)z;yTy69&cMM$or*-{bhOkX?fgXN5gu58(*n01*H4` zTbX`RnKEgo%b+`*L_OK2H=$2cT}kN2`+Dk1Kpr7Q#-5s9csCy>rX36$^5BKR${b=n>$sx!2^-9Fn zA|Zjcp#O+)6nIn;fipjAbp*fFdgyV)J?xX&w)>u%RwiJVhg(>x-hI7&wamjO z&h`nJaM~v#f*%)R+~5hAXf!jhJUeA!69!t7sy054Um5T#_N0fM$Skxr@xi6xk2)@_ znipnpoL^PbBp*fBi1%0L;e?h=*eP7FLBm)W+VFxxFE&|H+J_oXwZ0OQ(LSB6X&o?= z#+OfNk2Tid+53(|ffK6zwak#<+Fp3`Jxt73{XTVE3eIf%;&I*+3@uN;YS55F{Ix_Y zdp=VPS1y_$uUg$HMo7Y@Y zevUS%w5%ueftBeWxq8d4-FWf@EKaPzCH0E;_RBu zMWXgE79slXK;da)f_d8EPv9eiG$bHS<2X?9J`PR>FJ%syoU0uvXvHP&J(YvZWY}*u zMT-ydICpmE39*Oah57z*LMCFEDdm%4(eaB@|La|==#J>MQDLNSH{;u!%5lP%@Y$S+ zNIbpY#{H@jCan4lUsH`rGWe3+4O;`MpGeFB0-K{1HQeO!{o_@2JUz3U6y0<0s*eh1 zhYqa+k9>Rr{5~@TItjwm_QrMBZP7VV0+Y16C7vA{uc$kHC@$VnpWtR&YZWbLF57pv zEMVuxhu7)jo9lc~hBv0cM0iW2ev(Mscd(va-OYkRv07yrv7n)Hjf_X0SYk>rtvKF4 z?qBsM?LWf~;{Nn3;3Dye-0Y1`;SXHwjZOg?Yv{e8vDR5B48dY&;2PUKY0T(h@q9{LY9Tq=6J+?Y5dOW;=jfZA5K~&HQ8scFR0j)=-Jq~};7^~*KiIvbIkL=nL|NSM7DeJx4H_pYv^zDbvgOlhp=&j9YQ&^N5FM{`UYtXWWw_m zDntlj&Anp~lC!%df%C>=_&%(5emY`p?M7@CpSYyDr!ryzBeZW3?cqn0uU5WSC-f1& z>z0=s!fs!2{U7T?Pd|o{r{m5i)|;83kPOB8T8r~TU_%>LJt96-vJj88Cd9{DiRPj7 z1^?EodhrNiUx>%k40p#fVl4BNmBcsO=BLJL*&)!f_3-Qu5|3SKQ5yZCux1%%K~erF z;amHNc#U<|&AKz&&d=DsU^?!-vye|j4~^WuFwS(+o^i7k3|g@|hxT@H^#@_E)gQ6n zpF>6*vi`kgn4I?h2kvLvr4cQV?|;%~B4#32)E9nC=ybMi-4;zswPJoXkv{ys-GeABPGf*cl8D+$bG|}0GS^2O6>jSgSlqk)`7Z?ROnav2)Qitt`haC_tYjVZH=G=c2gHJ70V; zH!j1@Fc|k+kuO8aLNX$4{eUAs$Ah*;io`Xg2;c*;lL6;RBPl%ze`UHO(33!vq-ol9 zM&>=BQ1J*-Z5KXk(G zt@FvQ=~aP%$hvga@&eQm+Ed5=o;sFvDe?Aq>;acy?=`a#awz2Qf>xW0{3ucaQUKD5 zBNj-{?!xYt{V0h?BnrqC8CWzfwv7d+k-da!hKF>QKZ00WhdHc^IkqG~IlOWt`m)m* z?jf<6R^8pO@EiQJvD`F#k;fU=t-&txmV1=2=OOwPyd~eDTo{%4j0M)dRyi0Et=7Pc zhR0n4t$wPDJ_b=6wD%k^J!4Ej2|nGpLwq5vz`^29C+vR+`f)cRq%uxag-@FX`;~P@ z?}#mI?w8(Aik|uARo~oPEpijDc z{u*Gj=gjwjU7%x zF{ZvAdaWbfPML>BX^66xFLx}DT~?9u6f~2TE_)vl6o}T6^2+1`5?}T#;@ZWM7bp8< zyk8wRB~G7fRHSJa0`q#<#2GHFX4k@>mM&UI_sVkESS&=E26{3ak+GTR9HaS9Bd*I2)e%--RKaH;n$_SET3T!t=WTQ7i0&jAD((iBcpTwP29(Ov|d47fu6{X(k{OlO1 z9*sITBKab@ZpcYH>^MNrPVOV<(+3E8U_$-0XDckiI%6O(GT&k*H+ht3aF+iO=j=fn zFwFpJdz*_mQsA}#>nB|!0c*IK#3fq!{c(t00GZ$iNL9F5Uzl3-6*(HaE9e!dN zSE2{cm?-QE*NQ=%>cfd4tX8Ap|2*+a z$bIizm}~sJ$!FFXI~n}5Jsv*f>37{uuKQQJ(>cNO8U8!mJAj40y`hBcm-6#_&?o6g zbw~n|`8UYuDk%@|gY}ePPQvVtF(;Tj&azID;Ii>pIdm<9m&RI7KE4%pcWaT*ubF)j zi{$ZGq~v22YvF@pMGj~PrN6Kq?T9dsmAJoOT=SE^aV1%(ojlok0`guOx0K7_1yAKK zE@SLbNTW#Heby22N=QbM!{{12jOYQGR-+JzC>sgV6TPIVSd;gQOB3c@hi`R=l{9AP zFD`Ye$C=)_&Zt@DaSDJkdf_k7GeexHG2Z?h+pC`??#Uldx$jrtEo16BBc1bdt9mbD zii*>v=p7j--`bCsKLB`}7g8&)Ip6T8_cG#d9TtHc)(9=2zx;Qcz+U(ZpxvXOnC9mW zPSTBgB#+GruKLBb4N_J7AHqbDZT@@K8aXlB<-dc`eQx_Z;yqf%q_oeD|Gaf+HsYte z4v!8+H=sqy`i22|dk0sVu$M15*Q93P*Obwk&ou?(ie=6<#V`g$hdtraz!R#R(VD(# zl5JAF#urC}Q%{J}i0`;80u%e5EunN?%09#eANkPel2_fEIz}G7vpD$ZmXxGYu8lbtXIp{_UW$82;1DWFm90e)5tVM!u-XSZefh)c9q=W@_&ZR`}AT0rsENHsT;( z8UY9`;&OPK*Sv;vhB*J0WZxS`r8Wp&0;9xdJW4I#)2XBA-BX@=SFDcLDxj8-9O-wl_It^QG(i{`_A)_Rel7?ZP;QmY^^Pzl*CVJ zbCmz$I&g2aAlv@5@jF;l4ivxd&R)g}#juV&SI$K3$&MBVil@4lF58SJXUfZ$QQgXW z^Y&+_4hS>iB@{>5eb3^Rf4FrIBzX`eYhfsE;xWr{icC}-9~%Rl01oFXHH|8PP(j zskcpEcF{JSelIbbT49eVi8lrxEiqkNmXTtuLl0Q|O7DO#{At$n_mDy7T$-)V7=0R6 zWs~ugK4Tr9vCN%&Q;JqjsK32WB66N4EV1vMDUic(04U zE8?iZrMzp8A+!17>RG1iHa+C}eBpH`*TI*Vp)nk4*&yKnpMoHq4#@B0wG;~=hEId6 zaMWe$ZzT5M0y`_d)kS?#lq`GIkZ^ilHs|4$ksFco$j4isK)HxUx@>y(jKznmIP<4X!HFx= zR;91XSd*2Dctyl=H0!73^9&)TewXJ6{MIP(9>h|N(eWiOHg3xXz8Gv<46X5~xsh6H z6fNw0=VlNI69!#I^x>LQ@Xj>fEK;fW1b3eAvL$B3k zcRNqspyvsP>{+11?^}F-dbE*3cG_jM7zBC4sw&{5Vc6FkpR&Pgb{pDlWavI?X2w?V z9&;DJV<$s*Tc`Eh?F1L-`v#pEL+xqzFj4YS^w)rBAx_XOA1L0_xd|(5!okGl@X&QH z#hK#{QZG>J+eRNuT%3rxc-;w4%)$`+c*Gg}eAW20@jYkbe&V*y12|Wtv`iWDw?T_s z!nGPS%m)=5`4!2CXJL3}!u4{bQAiC)VMs3zf`3b-`LJ7$MfyA%JUfyJDF(^69R6wE zgAX^@Mn8%~ZKMg(_ppn#BF#toLIay>r1?lQk;WkfBk@R!0ZZLL#CAd2hy?vY@*$X$ z<+#=&^+n>5+6KUf0n+D4A0m|_?Lu0+7e4Fvz-|?Z(pY_jtn}wAiiP_@9R>>bPh+;y zsBc*XwOKd7op_}>9nRz~Au<_fM@e0fH~D6!%J;!HEJHo@#e1T`!#r(;B|7+2dLr;t zJz{EAj1rjbS;EiG51VI#X4Dyfb{=Y8w2al7vQN4uRP0(v=jX2Fuu~X!aXGM`-yZDR zY++OQ?(Eb3xWW=+9HKsSPxKSM?Dv4czqV13y$-L=%K~v~t!gM;bE1kZofF2DMwzBK z2r-%Z2+E}IQ~Fs4Ku)HDMt}I4m!Z2*zlIELvEl4PO@>{vtqkiUOvTqxCX?y=6j+(_ zb{oIbB*@-;K!^ml6ba5iX3DcLQNn6wb&X4DA(|6S!J8g2Fx%(A8Ug%5KN1y^POmBT zMCm3$=`qsebVI75m_)IuX;QWY~MMZ-*&`tElO)6Gvhh{DqPg{41T zlS8lByuPzQ=TgfV>?lb|>x^?<+=?@Y3)3@Jp7pw7z1A6gI*lY0&_t2yvG;FeNmmYO=0mK8>79aao;ff+lNC zk&CZT!^`Oh-F3h@Q(f_7x1p}dUmb%p)phvgy2Ce&9wXoI6W&rh8CK6dz+jB=JInp9 zSm44IThl%npbpgO;3VU+bK1Mh(W&s)cV2Ox;0!j!6AoF%jQ3*}cCn~h(k zemyOR_K$Az^8Th1%jddy^*n>0iNvjfCw&r+)Blna(~5z?))_+<7Q1BRepmF0i`ip^ zF!&W53_f2krsnyV`j@=9ke)oxT6jhpt5`dEvjP;-0YjmAoN0Yq(m?`Gp`TgcJIguz zpsIw44lxb2Zx{Y%-;eod7@$O7WVuGE=Sh7B;m(f)qu~=5Siif)k5M{4QDwPC>Jd3Z z{SF-!=ELeTc*yN;pLB3Le)|c2J5oQ#?0vVZdc%NFNVclmQx1kA4x{ppw*+RwONP0a zD=gdo)7}=AV~R%G$D4Cauh=(W)#}BwmYVD?XM0z&X@h+;Fmutenb~w#{Q|USSRsk| z#TA-=!|1{o)S*A=7$nrQj+2aXjs7t0r)##Y8UxWg zx^H*ono+)*6_QO9n@1i5gTDCyGovQA;QSsVz0GjZs=usRUUs<4Ils%lG#y?V zMuI+_-kEyXALC8$x||PpH)MNfh|0m@ckA0i%Xcqh<44%KoMXDqxF%SVP1KuRo`=!t z0q?M`9Gu+J)&KvI_9b9Z9ofHid+(;%U051yXiyLmTTp|FN!v7679(ym!DW&LOy;5{ zGD#*w)M(?97gjj@8h2pS;T z-D8#`r?`qmzAz9xMI9XMOhcF4h79G^~oH_&Hes+fHx zGwQ1uP+{ShXgqUMTd}SMJP8u@gWacfwD&mZ%`p2+ZAx4n-%TJpXW|UjU685fSif(WYf9&)Y@0-k&Lua2&pE~CB_@`^_PSrpC{uQ)pdMBw_ z`2%?MNNGq@kQ%SJasMUczhWFuBA_&CsWYAxbsnbm`JIR6+x41>%8*L38SZU`{G>VOH=2o_XNSh?Q*n zTPD+Z8Qfn>^7fkGz$8mF*21+QrZ}8`r;kLnUSi4{1H96-|MG=Z4jJ7s3uNhfPlA zGe78%zVwpi;H*D`x{O_LMKJD);0nYUt0;cGTweSdwB{s?KQHr;6`A-}+x}LWltcys z@5(ZuM-{fDI%jx5~>pjZ7MT74Ul5+ z;Y1EU179Nr15rv_ZR!L1L)hc>%Hq2&zE@g)6h4*iz_(I-R(m#$#FYa*Mk5=a{aX3w zO^Q7ea-Pfn94D+6*R{?Q*q0jQ7I0W45jp2g;1YZ7?RL$+jacDg%+tk){jtup02)Y| zgFjn;&hia^m#zURF}#~~H9IE<+6O{ZA@$c31KN5_&hRQkULSvH#VcH9+8f2^^OUnVnDEOBu_MJ{ebBQ@ zEb;&e__4s*?;<^ndvsna+3#k4m;P1dYRJG!R9i70(6`nA_0>#f^o1tbo?tFjT+!XG zhi{RvG*-ou2roXr%dc^vuM`^W@|JZHMHkar#QB;%?F8R(Iv^cg?8RT}G{uJ6$8G}0 zaKap=v+hkH3YNU>j!gO<-jTE|03S_aZn2M=3aX=RPJtP3dhuU$jxJ|nF4mi38y&|x ziBZZMB|f0m6a{Z9NULCr*%XBQx~&3{T$*h4_+M>vTMzfyE`cT@(WX0{Hu^OwX8MF3 z79s0a-?=2H^pX~-$GJ=e^iqGkA?06LwP0@g1R06hRIX&s=W>D7L?6z_^e`-cd z?5nJ%^-(@aYVzgFF`N8(mBhr~vPocJuQFuthqWy(522fzva~w)1XnVH`ehI1?qm{Z z4QdQ)_1)S1uJm3SLmKOOJPFTezqC4lZFaTxQ=CiMJ_B$18+!meyD@wQ&i-c{SDfy) zQ^0?&wSPbGs}ua?YWsHszn<@DKvdiY!AC#6os4e~RDd*eM2CL2Cmoy}bb* zJfx11>&&IoUpq_31FKv0yfd7Cznj5I??>P4S_yjfa=(Rn1Pl+}6``*n?ZJNnUcdN?T34mDMx`~nKy|8EcI+fJR>8M5G-7T|+BM!`K*GbL8 z&_mn+9k-{D7Nbnpm+|<FIJ8lpMu*Z1C^i1#!2N3icV!xtC5&eYTQ+#~Pt@miEH%}5JT4N<@Z&BY@Ui{UlVHKlde8u&a z>?8gSWbPkB|HH#)g=0p%(EU)_qyb96djQ)mbohW0Fq)*5c{6Z!H>ipgsQrpovA^!7FGbl$i95mlnrPp^d+3$Oa5{by>FE91bJ|I{ zc46E#?#f8THdXPJFe>v>&!r>m7)gp1`#rXe4%6Zrecy8kQ6Dv7RV_cSbvP8IIaV!v z7fK9a)?EWSZ-X@AKY)+Zan^sY4s;(<5E7jy_HzoNf&50^pia$bx6Ok*lTSb4{sQXz zGzTdi(uHTWu#pH%BT+vomK`qEu@wAq!bb_2RenQyc_9O%=i?ZK zxfjNA7~Ma0-$KkA%;<6Vw{#7V-t8_#TOXcv!}vMuF^W)j^Mjs;Ec1D^{=iM`mR}&v z3_oaU`?Ky`CfiQ3gSi|L7E@dQbIq=ey)>5PN^n@h6_eSzCjFR<_O(g1ZQjx+x?b*+ zHj~)!_O(l;%@RY`5p%OtwR?-QSl_;OnIShX93B_hoZMN>S~XJ~!+U$|&K=8pYb3=v zpeT1Qmlf|`Aurzj%yu}!-hNZ_)%Kg(kG9|RIk5evu6+B=fGvvRZr815WqC{%DTmcZ z`GG7+c}teGJSIn0eqf2b{J@in@&iw$H;SgoA8kY%8*dIP--tGdK0YmOU~c9NjP7q7Pgb7#Rl9{!0`!!j zcBl@TAZ-oD`D2Ez+11mdgfGyMSZP0A3=>Cw?a&$H!tC#z44VjiGXWZ8h0R&Hn6-w# zV}{o?1t6Cg47od(?t5z4Q*YxtOS(tkyCx2N=Lrr4q+Kbs z#^b|S-?SdfJC%#U%ktww#MQeLlHI<({A%~yS~pp0#%+BOp@ObW1Pw7;8&vqs?xK8L_k z1`^yay8e?+F7-_7BjPU2UQM~I@MpmK2wo}_J^or^ zFyeg5u)ZmDt}JC2gLhB3kV1S*;(qdaZ)TO-k1N$I7@Q}H`*6_2&Rc-uMVDK7% zL3SSuh5;Bdc!l`=7Igpj?`KCnUdN(R$?+(hNnfS$6t+)j6nW|vW{ zaZG)vsEJKs9h_}rFx#;Ewb0!LRwMh}&j*Ol%dxL8MhU1plldp7he#VFiR+nC4_jtm za4N+$e*aGT4SG8Rd;k{k#UZ`+jeG2~kwa=&Iv2hY#`18`mzPv?>K zA!)(?vMM6M0inC}Js3Y1pS>T(tN#JUi~j+}?*L;5^u%`oCJJBU*KQa;MDBGAx@pHp zVQ#Jy*Mt;ng6hc;DP0pG_sz|bb~*>JE><_YY$7av^?pOEnHj*Ceh$gd_{#Rm%1PnX zfj#N|QKPHmpwNT%69-_CAcuvHI3MPSwg2z5OD&%FU@4En-sIy)b=OS}d($vK8B5Dk zP!15UPIPcM^8~=}?YFnL-;}J9vU_r=bwpj0>=o#+F+b-LeVt%ztP@PNqn{3YX8p~8 zRoI1Af#Z++in)JTzUS#(xT?Zc&8p9YgvRwZwJ3Yx3BNO+H4S_6v!)S#>)|tmax?zj zLf{T`t^CBk$;7^0?fma^{n}Tc%Z{(FWcD-LlG}WyBi2Zl)J*}_KwDSu!II;?*n$3_ zqjdR)|Fy;<)R)0OpoLxuD8pTynzZ$xczvuT;ECKn%G&$r6AJf2yjLq#B1WDnT?J`L zIV^EVmFkotT^FuMRSxhL)%+ctOM||2pFelLhFCI48<3!LoiUOf!G&-I>?Y{2?P*bH zG+}dD9edez@McO?vTmByz#T9zJa-hazeOGD*ID?Q(!j4(t79&Bs3v^3?3+_K1DC>< z2PHwT_Y9<$n({DiVNk!z3I5WghDc5mCbvXdALjN48&UI`nmP1O`4r~P5>eP~9x;e42T2XPmEA1)h;E~w^LU>uC-_xpcF+z_OP(%|JO40AMz z(!3wE=^m9H_G}v_YBPN!44Xh#nPht++E46D(y2hZ6ScP^Hf`(xE`Zd0z=s&?NMSwk zKIYhZ$p`X7V*&Y8mTaeSA7{c>Z^=>muI!K|d_1^s{y3XM4~#uv9%B#6e_*V?eP4@A zv;`pQDO?%6q*2dWrrv)z1M_1M4IqT|vTLFn9e13+(+$?}8EQCSR@yh1f2scw*Y}&R zU0je4zlBuJ1S`UC`bf>?FWh+K5b`lYeH}f}*T@voE0H@IX?*B_KQcU5$N^!RF`0_}OW!n5Le4wC}xf@ui%afpJO7&x>ht ztk3^r%yq|S13JPg$c3QI#=p?VpK-(b@mAP9p^SY||D(V)2Bm+{Vf$Slu%Bm#Z9cPK zHX)I}Y38_XH3fKA%$QVP=0;g?6m52I^FUn})Y!}D`I(q-e_T45fX+cr<> z!1dozn`WxN@>EYVT7L**_3%LZ667lAFj86S?LNAi`dwMjeCdKN{&D2+*;{|V z;~|@0EvKcx1+GS+|A8p}lPd=w*+O-TQ_02J;FWm#Zo@?Gic>hPAkX%K|HAql z_Xjs}LnTfWK9>c({<08d(j;9LploNkEclot+b;_VCI z=_r*!xlhB>H^9P^zU#>rvaZa2*BAXsI=RCK@$J;yb7FmNsfK47WK>)d{D}K;dzSuf zcKA|FQrNO+OJuHO$DU=(j`wmY#5({nr5dK7ozX~MG=aw$1nITZ{xyx!0|^H?F4eE# z$#l7aa+I1}pY|%!)kavG>3vuU<HWrl}1_0LF`t(^OIyx zd>=+@X7AP0;P@o@u7m0!)gqdvUeppC4?3Xw5{aby#QDycw5Xx|Q#P=FJ`CxgC;CPA zPoh8LWFl`kb#&c`UOu`qceRd`YB67!7(_%g5W{-F5Nc)|B=UlD1y9)H(AI`u5{DP$ z&Bx3h;*PYlGogwx-gS70T;c9abqsI!guXV$1Y_3knhR@mvuqV{X<+VK`1>-&?V0F&^UG>PcVgCYw4iNCClq{V^x$JN~ z!*A^-)5 zBJ%tHDE@l>U+~d!_Z%P1%S&lKK#E%Q3_F??8v>>>hwo zj@k1uw11=6;p}pXlLYdB_m%8GYPGA0kT-(=YTRbt2@3}~^)5SA6Vu@!jkq^tfjoG| zWN>z)yXI7k=R&|vzjeh1=z)E#AO^r<04#aO4Jn%jU~y|*h4HTf76VpQ0H`<_Aox?K zoE;ezRPPB-AE1fCgZ_Xx^TNmnd>zAKsrI6!%XPWaTID}b{=T!Y%6Fh_@64-`>b=B> zEA;d`XagsAsNi{l(YHD!`r8=i=FV>c6NS$L_zod$MtTZq39bVtWNcycQuES>qcuvu zl5iXQm52@8)azH!x*BUGQIFfX6!*Lj<45&bWF^6ctRx}nh2)x@#Nd~iEP|vMXNs>~u1IRP8Dgxnp^5Qj zzd7xZff;&_dRzg|ydq8gdSc3Smd4HaqKC>c*RiS^^vrh6{!qGwWg#ycrk(-3FDXui z7BaX&ID7T`h4D$SN_4V`$=~e}xf1~h(B%o$*t5GFBHHD zlJAkkSf}HB(v{-Ab}loNYhSL<-&;i@6^&i430;g)W??4k^Q~1h&RLghw;-kTc?|D3 z`b>yLHSxDXBoV+rVo_&R75rky>AR$Nip@S}<*?#0=(DS~a6ZSr=IB*}iGg-_d1i1m zb}M*L&zqsimEhVs=BvyAOS@Bhj6{oksN?n64g6AjEbA*}`@aB2UJP1q5gDZR=2B{} zNXI|ccaLW|i1}o|JCwhJs2wv1zf#!yk$ZlxLoN~NX~>^3CWQr3!m#cuyvwhr48Q;1 z+8@E+>HTl*PZ6R9+Ls`Qo@MP8v(NG2GkYu>zz>p{w!>4qTSir;DL%lG1kIYf8ESa9NP=Ehr$d1#N|{yA2& zkS%|BM?r?C(O#^y^jQ2kk0cqsjlY#zTa|I<>b$B!d#iw~GAlH3v%GO?T(O0PR$!u<&8S<8c2**P2Iey8#=$PgRCDre^3v+AS6yq> z4uLfODLEJMG?fab<&3-nUO55^CpT7^P0;GDYuaWg#@lCXvhn~+iZGtMn@gg#;@RAT zXApCicuz;1UX$N9f~uA&YH&S#lPUAD;JvWTL8)w~tL&Dv{0i;`aa8+2Zr?8K@y)$+ z#&-j9Iij19M&==Al4|0gk|WN(VScFoSB}JX*dI%yBjU^LN3_@#^>sp~UlDwp7m4&; zoiJZQ41h%s?LWypt69g4{R=#I57raJT{;IH+`=5T+OjR#t6pB3ivE)5jgBPffmMZ@ zQ>{eJ||%1lP@O8)QJ~_V;y6`CVd6V~P=Z77@#ssfb}Wo@+u(Zb zSEl?+M0|r(Dm-u~;+u*;(Kiyh+=gdIrj8t{VF`AVd&m#~hGLwbx@LZN!* zp#Q8eNZi8vVSir%MQr^VNa%w5nOFlGg*5^CQNon&H+!Aaq{LV>X~s;(TA8^p)ZbDF z-wsk=UugEyxI*%jXzV+q`9qyOe^ro^fTsd*jz)XYA{U6BJkBG!Wm5H+^zSp{;ngPI zS}SBye-;G>TtUKoq8f5c{By}s^?EwvwO-(Q%!M7?Fb>fGn0L+IXC*D4DEqlrs+jna z+OdY?=F;v(wudOKMLd>oVav0a<~ z_i$~hcIeH!y?X(7B4DQDd<;1q>k`1Pz<4zxJ&y9%tEJ>ylzr3u#637TKe*Z_o%;33 zo8g`AbL?EEj?=TNtB5{~LtKSct#*9XVj*77#7jV7mzo8~608y4;oddibN=|fHfehl zH_V^)oAg&I*I4eLE*h7*!iJGhsm6T5>J8F2nBqDiC466tN<+pzVy|l|&OuaziJ!F+ zEmN+5-uXnt7tl6)c_h@tgFay(tK0>D`*V{e#lH17Tz~3$I%rReih&L~*5n6)O#!LN zZ`bT;@sMv~PYd(sj=1^RFc zK=@aO^lkYEBs`i8&=bC|S6;4Pnr6d*qUnr`U!f}JF#a;P&8;j z`m_^Idwj&ar4Q3TkWizKWFGOhB;XlC&)T37>4}yR_&$h(m^R8fGToRdv*u;CW=gqH z@dk^5A0_p$9?cA~x+5z3q%*Lo2!tMTLX9Vj-Pd04)EiV|nBq!$2F5s3+&lZ0g3Lbx z88_0VfjMeNPQ^n%+*A-{I&7Y5S6O_HDbwZ&T2llkqvz3d?DU)m_K&WkIG5sC@txz* zk4C4zWQoQZokq2#QSz90%MB7o#tM!|M7kZtC0Iz?HQ3-@?NzXuN0n_?Et6RpB68hu z9qC>Yl+pfHHVJ#Lqr%$hy4Lbu+ck4Q`Uoracq}^3=hWC$R0Xzm8=E*GvK2pqg(7V169^qj1yt-S#Wx z8_HN!Rlnn4lB649H$wXpk#Z72zg_f9|0*+(^Jlf#O=b0|TyU_Kt1x$6 zWI)%&L$~|dS)!-Ui#&>&-=ZCgW9fR-rhAIgf=H(O4wB7gnTH)G_hv z0XOP^_EEb-3jK2$E9TcKh4^mvyW+WH28~abBKc9Mw+R^CH#*-RPh$KU;?up^?}f~{ z)El3UlQw2^H-pYr4P&VkLAW@sn$ZI@zCy(RvX;Ngu3N{X(`PAu+--eBcz=8nZl1ig`61O26AcBvV( z&x?>7{0aL~K5!)xk3_LQ6ApVv+XL{0CRorD>u&)qjSkA*ppkstu__;SjHbQJo5r0o z``IbAP}fxGM>-0vQI-bREj$V8B<^fbfThzlv-tr$^{XT3e|h8ke|jTs;0?FWG}^wq z?M??1Bfm^{A|tFjf9yVq^@Cs2@3_W5zp1Pe^8xej3-oU`a%H+ImCBG*DGM^oGJ`We zfu$QPY{DUfi>JCU-yc?xop_EuOW&b=2Y=>?_*oOu_H-2Htg)=C+|yC9WKYNI){J)B z>LZ!H9NzUyx6-lqx886~>KU89r(;X@&Zj7caZlUxri}J|t4|A?!h-WR2C?X`UrpFV>4=*88#bXVpSZUxUULFr==r*jS{*dS{_`W>v2)53dk zG-4oMFdXN1-}EDyF6^&UIsMoe3ovkaAsYb7@9ieajhoJz0pXd|B>d64cXGaM>v--4 zVj5C@@OSkWoE7LN?W3Xzdd|q}4k~bvBcum?-azG<8D!b|N@-M<7!PwnvcyX1Rl1kq zM4-OhjtH=6ge@3POgFdjIgGSai_*jK^T(6VpB z4nyjZSVK84bCaKIQG5LEEGd6GnJLeQHPD1}e@cDVzxlZqnObw{<>Y+WBHd_k!*%qM`>l~|D0nkr@EAE* zLNE7~Iq92gocwVzTDojwB^e`)q4k36@cR)s$0PSsIS4E=B>RHEQ+c$X(aXV^Vqm9F z#xQS2@`ylFzALcUtfkK~*hlU3zBD~g^qfQDi-k;*H^W{*&u_zO$?*(6&#TAc)lF*Y zIWq!##b0snl(=(4H-I)be2?g(`P^p%(MWvVm z+Hpphv=P3PN0I22G+xite*}Sx8Adf!r(-6QXdd>)%YR0#I8o+l`YexQU!Kfrx@GOM z)&)}dy&{3Yk6S)M6e#VX7?~h946sLX zQ7m~tueZR|&mkfRHAW7^oK?Nh?j zV0--M8-6}(EaTz-D$o8rdyJJd>L|yi3ZA<>rn|oZWO?py&}wHU=1tN+;B=7E%~ji= zA@v&jH)mM>wCFa6rd!?t-KSw|=1j9Jw`zkATFKa(jtj!ixl{{4ZU< zIz8^Ycctr^Q-!l(Bwye4Bi3wQDeRvB6NODS0N=Ct{ad6FLu)@65QK;j4AV$-zC+i` zms7gdYv}j6CO-pqGy^zVL)YBTD2INh#M5``N^s6YI*3$)vCMFuIP6)n|>%y-|@#W#noD!55j{o?ex z?`kmWxa`#2cV#x9I_I2iR9SpxWCNBIq$x;2NHV0hHx=;Z0vVr(4W?H0xfES;Hc97c zf3hkH(U1eM!XD7#j3mfez2%1MIbkDoH*k_;rQzYwq3@p{#}l=9;wgddfhEBD^u5=9 z!Wl08>u^d>ud*DgBw-w@vkI=Bn+7hU-8Od;_{k(oQIv0q-=;1kG4mmFiH~`wX2O06 zc!*{$NwCL)QU&I?13g{8^7xXNnK5b9mib^K^&NAtw$Bn~?Xd)xTCF2XhDG~W6KaNq zjZXU((nMV;yr@*@qva*oyTiW574OnHR-e*y+1sq4=|QEwS%?;0x-BcT)HmC=bX#^{ zX`nT%+#j|v^K;Hw=VhJCnwMReGqZXa#$>^t_0ej_#oUrV2U-eq=HyI(3=*D&vA(@P z2Qq%1sa^wgppt(AdH`1Rd&l2;`$vObUXJsX-yZPmaP3y3g8cBFf++sd+i$}hoRudf zi;=LG%z&qe_cvoFAuo4XB6vyvkAg5!0EKd?NgMW=VD-HuB=~$L)H1sT&X;1fHSkt) zc{tsNGkDu`O!$k?S0|HI@Gl#|%lqirgTSN7C1^dRvp)zr{l`LV?X#Ah0{2O+U=5>O zNR1<+k%4FQ{sJZbm#t&s^>G!+L3UqG0-WWuhKb+CRV1H9R6I$mUb0*4~Gu(%4}AnXl;h61(WUN#3dEPTNwT&K^upWklus3L}|Pr`l%dYU_* zt`n|>Z5Q6dnM5VsfSiHt)v&mER$1#XslS!0%36kz4NKxuIX_-6@v!`q8&DI@`CB}! zIaU%zBj8=@=}YT}FNT$v4cn|b_!9|G6GL|jBo-P_Gx2(O5D$Z|8LctjqA31H6BFN& z{%81;n2R+>ie(*b&p|7v(7?C#^J(((l@{OSi>fZYnsK-F`9<6=>Y*xXgy^+Pf>xVw zQky6G^828G7_O(#`sadIl5e5)yKC1QP&=j-t(CUGpalc`!e05WwV$VU$YSl$s9mog zto>fysF{3|{tZ?WL7TK@H|*Q{r&J*;p>&!gvs21zvanEauxm}c&OYK|H!e>n-zyBEP zJKz2)eqFJ)z`AOy?G^Ei>`^t2uMjq3WHgjon-R&Ep3rmKI8q&Eot>+)U>^H!GDl(V zf5E`{D0(65sDDwnVH;iF2k8)eZz^lJHA};NJsJ^!!m!YBaLOD z_3F~WQqIt|-9sh11_$pquJEZc;~lfLPH2ZWj=}O`X0U91CVU0lhuf1lkE%e+bYPOT z?Y@VGUw;fe(=8{lYuob={YLCFV+@)jxs6U>mq82xtfBFKWj!rwr`}k98-cuMJN~O&Gc|t9zSuuXAGhAHpZ5 zP8zzJ1l@s2*dMmOuOPd?H`r7vC51mgj{s*$9r9r-q-5qA@R49U`vv$XXP=Rh=9eH# z!SAK`U4-%rxR!}`HTa!^a@}Rv5h8yOX&1_Rj1D+It5&Y`Ffz0i0!*OUbj#q~rzUg-hW>5NRgL?;{_E>r+tPj`Fui5h$-gPM>2i zR`lHe^M160+|BRi;SG0VWz@`bnX89n^h#dY9huJTlY)B^k~fN1^_!}hcUI}-_P=%5 zG7@S)EzDpVK`o5brG})1q-SOB%Df7R&oC~O(^{BBJ?nJ6(HW4Y=pZ>uf>v5|mghoG znqy(B+z|M^^#yahXpzIDD-1KG+(gy{~#0JQ{ug! zojqtXA7eTJNd>*e6nI(fcb)9Vm`tbs5dS8Ys9!^gp7M3`j(f7|SsL(^)?nZG9K3=N ztTJ^`W)So;&veI$5kRR&NR@7oGehd$o_SBqeq3=0m8H|5~@aRswi@C09S zF`gxyniE{FRe!=!E{=lDJqnLwHWIOpiv$6 zMpfr>R`5*|OoGdZH~^%E0Un?-if1n<2rXx#{1nO(j#90gtJZVO)b-Y!YHg}?Db)Z= zH!8a3uL zbmSMBo!&D*)sxcYea4qQIqY0 zOWL)JWePV{8d><)d6m2oid^=p;Bs|>mhoZ=K?l704X!A5e2zCEd)|S0Hj~zHD!bE? z%w7-zc3x$_K)tcGX9R7dMK`2-pwTsI_={jgA!cvu*Ge6RG~hVP1iVesi7(mTIhmnjF5kn)6+f`qwML+fCW?zZCiv#JPT5;(NU2jSM8vqZ~=XxBeAx9)!|c1$peIcr{F;DqN--@ zBDc+a0{Y+b2AQK2vS;_Nk8;B5Kjz; zfsrKq-h%zDiPGKd>44kmXPVR>eFo~XknPT<^6xQr8tLe&6{BuE3QsRF1!7Ib4V(ed zn|51ca`7!S0lBAzgq>2XQo>i-!dOHv;(a<36Q9n7FQRzb#+SBomezN{k)NyM+xzmf zK^YPfb=FajIS^GjH5XhlMKE{Nya^{_(xxp)0jy7T=P$kM%IVHT+1foNmq1%#CFgGq z|LJ6|dvvGvS60#Sb~!dxn()<$9Wgp=g6nUv`%^`&&~5c_(k~&u zytZ9=csE*G>yjS+IQKN3U>g6L`+ik?E{W-~Kbwp7#rWq=t(u!#!8LGt_(Sx^9hc+t zCW+5qG2fc;wW*)7YlnoT=ipxkF*oLa$-T;rwS-yLnNQYiVSVU|@Y6Kl3&U^jg5-lW zBwPZyG6A=03tNubes&1ipIvuD(Q$~v09(~3Z(pZ9ara`r@X=C5vABw!q`f#JMA?75 zuHcKHRrN@F_TjFj(p-k~nEHE{ZJa`nX4R<|?I$JpWO z>F-`@W9?N7SRZ3J3mpM+(Y5o}I7GtHTQ0gPe$7hF0+s$n6Qf>fQH?j@3GM7r{Is5K zc(Yt#Uz9o@cQ=FUzjFB;6XuM>#Fy9t*qH;7aH2RJ-_&~|Tc1U}HJm+Ek2v=2*Mr#b z>?yg-!*qs7SwHTGIrm~>#I)QJis`n)H|3;$S3qwJmpI{Vv+G<6#Ui%5uJkTCYf`%C ztV!;gnoGjBK_@WCx{8C(OJIaoovXMIEBbB)9BRh!C~I?43`TJqdBf!@?Z1V+9Qv#j zd%@CJW|$=eJhAf^>V@t_LBl?q548+)bTR za~+8Kg?YPk6-WPfFMYt->uT*KHSbqI*BrL(l#Ypko=wHe*x%2CUfh7a?W}@4+11}) z0=|zSEdug-H%;dD!{gSPB>d?9rQpPaHsW*ptkt9>SoCglzn$G^=s<$zNo5X?NK1g` z5wl~ZMK=CHXvTfst*?@Dk8|WfRn3E}cWMIbjW5e=rHP&9#g~*L=yK)u zehbLA_eQ+ohPi78c#5#+bh`TcHOT*tobpLVvdhy-*yVuv~|@8 zW`F{tF$AatOA6oX{~V3Tba{D|DJ@|@YjH5TjTN$Mcg&we?pW7`_9g0Hoex3lnAQRB z^R#F8dA0uGN~_D-*Wjdmf=}z7sH(cEXz1^`Ts1v=tH=J2?~S`mId?VAR@d}C68n+k z3n$$_-m=dT>v;F->KfMfHKj%IE$KXb`#YRfkOJ{7O~||N_V;@s-?d#qPD2NOD^k1|X^Cno z($Vr_ng8fzJHr8ujwx>(O^p0e*jb1bs_L}JyA^*N(Kuh2kjPB6;QzAf`GPJH{whJO zNbOO;bMu8nt(@Q6ZxIr=!gI04?_4aKIE`KRN44 zBAye~Fv#Shs=U&#LLVy-YiMDQR-{cSt-GO1gK`OHtWsm1QYod6X%wG&lG-3)trsas z^Vg8A<9zZx@-LCLwDb+wQzjKBoJE;8Q4w z6z6H1%XNoFNNZ(0ra-G!$47L!xtGVF-NUFzBYaX#oDz1>ENf**Kn<0PMdB%6>~5_N zX!uOP6_U)>5)a6`qAas5dP|4vM33lA4ixP!TXy<#U3O{;W)%F}$zHS|q8ofO5swe8 zp9!i;9X}dcB$W2uW?KNB`8W-@d)rol8lTERn%62*r3kW_WAn$2^{{sXKdiux*~!JR z7hMyYHUz@gzM$AiSDTL418&H>^WjB6g7 zYW^Xp^cR{KKOO%|H-+F!#}rP|@|DyqOeLAtg!C!gDvN;KsKeFKH!1DG0UR+HA1-Mq zKHQH&ZEYyKxe}x0(PLT8Hi=&dzgnN%uTxXAH=*b`wHjA$E4)aZxP24-fRbd?FJD%X}gV#uGyJMV{YS?_p z?S>Vlwm~U+(&?}#K<`0F>Tr$wxQn}rJ9jSCHOc+-?A6@vtTQNyZ{hwZ#5Ozm54T>u zf_?qb*Hius-*~UjB!^d9irA=3!U@@!eWW^Te7<#Aca~A`HI~cd=SM)YNXu`@I_pSu zj(vUlM9kPr%M|bn8fJ{i8!pO!AG6bEDrD{F53t1G0a@^}{Kc$M@b`HYb6A3P~-l(^mCRmb1xM0_Sj0=})1!DwnfXkk3Z!#~Ptl|-0OTkm@6_QbSFsrlI} zp^F1pNhtpkPG2V+d*Si4o70bH^m9P1>5sQ+}9#k$FX{Ay^FoQ0RC;$ zSS!k=+f#FQTT?9Epq!<~Rk?JR9OF2}1!AwScg5ZA;$m2-<g_E)2s9JYwopk=+Dq|MLLc2*lo~lXJA9Nfa>*+3{tR4=qY)E>U_BCiz*ptoAIp5 zSns-iOOvKa{UBHlo;ZBJLHAeBhVq-Jy)87nWWZvW&!!I7nUlh)dAIue3qN1eGT-anGkwuQ62j)NQ{Kz`xUtC;}D|H6Q$i^=uO23rMW>iWzl~#v#5^fC>=~ z-jyF-n%-&Y0^f-gFTxC&4vBUE#j_Ri(6|Nz#wnPm_FRwH!Mo2ht?1_TEv20)t z({d@+!A|oCdwBk6HmKUK5$j`IP!%GRVYLY7m+H9as2wz}p0ETN& zoIWqFpmg|xo=o_GJJxqE+U}r@%nJj)e3@xEztcdE!up$!;6Hi}YFdPv8XR%?Xvt@* zdtHvBt(MSrIrdxoMA7=@Ypl!pLb#D&ZAlP=^iw;1rWEUv!Hi}wqfMy6hpww9G_0Iz zZFu81U`H)c2kcu}`o7+%#ryPL0D4C6wx7>RuCRxs5j|EHS!o%@ZK(1DHL0zo`0TFh zd(7gk_G2|ma((+xKDbbIu-@ z6Lta>8PM6?>Yh`zo535lf}fZPdSnaYUA_w5@@dGdkzPsN1bTte4eQhYLVZKNPN{}S z(FX_RZ9)%iwv0d2Us%05eGT-zg1ME@qLA-oAUaKkxGHaL8Ky6?Bg{Cdi|1U6d!JV#VKeMPh`Vjz`myz};2u z1+VRm9@ies)hi9VSCg1OIFu#Q(omk-%*gH9LC$T)lXhiEhbyd`wi6__^A)(tA^hkr z6XxOY?kVVfFn2L?bP0tO(j5l_IzvAJx}`lclW!yP!F!bo*thT8*^Ra4(W>%bb&p$UkJ1Io z_j)Km39ol_m!oIJYV<*U-^@uv-I{(BTyJE4=%F(BM>-EMO&Nm`}aM zPWp8|!2CG_xwanj#0$v>bBFHfKV!}WVZH=mKi49?HWNN!KZA}R&TxNe?(e_xDP$G3 z(6dJ_O_8PM0~`AogZM2qq$U8@cK7!8%hMFVFwiUJN<@hsapcYDaIOB3;JyOyVir!f zu_F-MlGa%{9TA8(@Q)}GO z>FKkh(@Vc9dq=0Y@l2DFoM|FR8ox75S|imiAvKnb3iAAKAjd#TLGtBo-r5=!waYM4 zxdmMbTK1<$e@fkky}S%(_F^{Zo!rbTO~LEboVRG59#VQmso0i6`BJTkOiGQqSi21p zZ^mPrs_wI8%+u;^hN`pTELdPtZzE$(d}skqQ2ZkWkz5XJ+P2|kj&4tN$Pv9e-W z`3d+i1Q#>LYKO*gvAleLi$bC)S`=Jt-dp1jPwG;wuGyeXsHtF|Xg;VVe4|bF4)sY) z408lojNgYQ{D)uv_zKw47Lk~c@ge>ejYalmQ8Mhx^mKofsa1A)8E9N}T5>FYE1^pu zS5qxx6Mxe7GsndJY~973h5Yb@?SMJ_qM{7Ej&(BpC+n^>dH5)c!#S@a^*f$rCuYc^ zyzO3P%JMREmV-o@_#W8SL~`yPyzP*ctBT)pR=3K%@4&06I}$~8s}g!z7%%kuTie#O z%>#78pwBoH-)2i;eMJoNR4!~4YITU)O#KhiakGoK{_8t7Q6FI*;CJ(BbE_P>@fIeY zTHrBpGEm@U$0w;Ulsh5s5wQaNAc~Le|j?>A}7v+L9@j3jLB*x=ElNis@lTW;L zs#8`Ovg4G|+ z!hiU6jW5Nxze;42VnVz?YslU_LdV@Y!tN1LX7)e3*=z!*VTV~#bCsjqpR3j!F&fi2 zC%9(DKRFH7rGTNvx!JtZ!9vSqUO1d)49)V`UNUZpBPVy1^$A3QzNn0-Go?;}e;=yN z?Oncr^3J4l9anCuS1RDmR%e*Xj=WX)!PbLqUqTCGRl%W9sV5N+eydG zBgxRtPwbtG*at|9H^7Dgc&Kd-^u6%g zgz^t4C!idK^5-bmBMn3O$UvE{Z7;}SHb9?f!>}Fjp<2Wq;jRezm06iO_PkQf`HSm2 ztW>j&uIwvKqt<(EQ($F#ZnI#{X}78CK3PVd))q$7*i^%)j3~vVg*KCkf2@FFdK3Rr z0cLL@G5ir;JLu|yrFenw0d+Brb7JCm+up$3k?&9x`yKEurt%i0_>|19D5D(pAd8|% zSw1S{BrMhp1@gBNpyMNLl!RkM88)PXw6}7T~cEP zQ;msGUgDi#SC?wAo;6nb-qo`bR=#7q`Agt|haHGzR7Bw%?`XplZPp{=ioa|tO`dvI zLs$F}toIXF;CbJpIF9ox(!S+gwioL?+U{58f%R_UU$@Z}|3ZOpIqm27f~rwbT;`;; z&*E)n`Hmx2#XuY1*y$V#Y8-66)-Ep%3fTrptukDWXFhbQ%H=Va;2lU+=Ef3AtY9~e zFcy56c47cW_z%$-mI77Da1lp*56xYia2rE;rIN;oa*usl0UgnA2k->E+z-if2;XZH zbdy=DMP9_j16m_9UIxqD3NvPREN1t(JN3Yh(WbT*TZJGawkXn8iIUQ&2F6qae^dwx zoUWwE<;W$-W%RU_NTGNT>){9oy)&b?b2|J5Qy<0nnm)d7MOzea?K4lZE6Y<^+UiO3 zQBF}zZ5icnDGOzdQ$s57rC+s;Vi|nfzqHD{vXg7U2Y(DL27gFm-mCGjX0a`o)R;X4 zIwXqna^JlmJAEeeFo$*#*ao+fg@!%IYzY!vA|G*lj<4_(%TO8w5mZh`PocKCP zitwY>bj$`-QO|Yvh`nWdHW$49%1;GZ+R%$#&(Yb|sx3 z`nW|Rc3BAQ;tA}s+V%}rkN8c1Uw}Ib3$825H`CeH2+NG5qt-EwG_37;;i;)o9 zF2o9|^mG;~AL+enAG>&X2{AX zi?|{ob@EVs_mky2Xsb8vo6R>JX~~kBJ0h;VV}1YnWY*V7zmYQBBS}?6zteZu z=?MK4B#Vx$e|8YdEy6r_Vz-%MIn-nt#B$ZwRfPx9tF&ZykKVAK0*y4Wi}FVf-^U-3 z^N)1}0Jc}|v&ED1k9JYqcFym9+?E7>Nx*tHZd>v+Wc>x;mDu2i2e|9|N5Kb~B_&?~ zXT6N_K_nB(eW15|P>w~p8D$H~0Vscu@(m=4+dSDTGp~SdSq-}705<~PDENrHRjN}BUd97LMB`>E`%cug1v!)e{A$7Nta1GMQBu#Rm=1FGKri zG%r;vVMU)tB}T>zu1&Wo-Xkq)Sy{51PEmqGBU8^xo&f0Npi-1-Km#~V*;+8`TdW7T z29ZjUl~8*_A!_A3&M&C3Fi@md@(#OU zys6(j%|<&Nc~!Bxd|wNZl!1x~V(WCnn!{z# zmW6(yR2I&Tp|~RNg6qp$s7tT6sLH)6ijsA9NyxV3z_UAntye9LFB6Z9_66e*X94*K~O`2d|_NQ$w-KMG(kWxcU( z7YI6WjRvRch9F%f1c__(9-ysX{h@PGQ)9 z5Y4EK=Eu(AZ1OeLK7OwT^2%B%rBg}>csD*Goif>u$c~^wBv$&~)w3E_v4dfEnL#xS zP%0GCf2LF}*vgWpxha(*P%0(=PN~HF3#GEmO{wgpl#0B#)Jbcnl!{`2QlV{pW2bh1 zI_O|3cF_B^_O0fKa|)4KvGKnzpw!9@qUT(KAMGj z1hFjL-{HXmI=Y})L|jo}9>f(~)fYPJ;MwLLt+E=}VlB=#pi~+~`otDP+Ky0~#i(hO zX*43GA~$M8N=1R3QYuR1|4ONN{Trns2c?jWp)4j3yjSCC4PrekepIAluezIkpN=#n}2(Itnk|1(W; z`8u5mlqPxTKhh+qX^1BI95hKaV4piclkB$FAd&^8NAAT9lJVYsG;Yv2zk6|mWUv>2 z4N804v-j|yjPLHH`0o{XV;Ge6$oSUYZuoSBJa?rVx1C%9S!2F}%>9#sgj0N#EG5}U zH&S3HWWhNLWe(+MP_`k>M|mOg4IDvz z=BP5l`BFJA(Um9)_j1}IrZrJ=r77gO(@ISd=oyJe5l&;_>LOL$m&?@PwuDz56m=Ho zP;Lu$`RkyQX|63e58WSPI4{U5y^9gQ8Cpl);JM(-Tj{S)a8F(=FPq8*;aqSenIKj~ z9BTnDNam$!q}F%-;0{S@4A$+iK%DLG3)#+YN#@V`<0-ip#T&G(G{=6{)FoPF7*SS7YFdo>3K#<$Q{K_Nyy);$$_!?o+11$;u*f zQogtC$IeKh_JK|rvC0AUA;)i%k2+*wNvv|)cTUgJ101D84_Hg9)+>F_dvO1UvM+&a z>R9_eCp$@41XM)SuxJrb5pYARF(ju3+_hd@8_>1^yI8wim$oKiTWf8LU@at8QEzYE zilDX?u!U>aYnPjdZAELPttJB19u!U3zyC~Pz}ox1@29_ECUfSTGc)IznP-2tqbHJp z0-cc9)fr0d%V8hj>D6)YUm^^$`sK96ey0@l)_1^%BI>i!mwETAJDwrc(9>GQg;45h z0w*n>U<}+DsTJ?sgFWG}aRFihW6ps8P36S-3c{gp8cgTrUx4r9uG@g~FT&Im3LvrT#sqD?SNG*mjpZ)=?XZ;x?W!ZF@Ndqkhc zD0X~xA8udM9w8aW(@qJj0sdys&5;!MG0ZU>1jU+qHc3CyyYBmVsg&821EK_tGB}Cw zKO|N%*Wuitw<8Mas6e00^M2cCr-b-zF*Q5jmN?95gJ~0zRWFhYIF_uV6>eV73||oiuk!5L3A|+>4SW`!L*KcS9r(P zXFcob+(Y1{J_Eh%r=fR^wV;{`90BPl$}MW>aihEo<$9EFAd$5qg$_(H?1p~t7r~Vp z1M*>uD!JGYy>E?nD)giKQ{F{Xv2@$eVsU|Nn-m-j#Wt)LR=KSib}LMjyuj~l+sX-# z%eTdWe{pyi(es_72CoBaWvf|A*GyT@n#m6?^yph&Fa=}P$Z-8(X#YtH2O2|wi>diD zCJAuwAx6@Qa4-l>MK~BIHQzRbu3`AM%|!nOt4Yyk&{j=GZLw~CU9fRO+=J&9M)chl zzADtx*D6X1E!eKPZWkBJ4N`n*wY}8XXza(c5)!Yi(Xhgvrt4cLBfN=hte{-r_^cmR zP)I?@K{;@IQS5X;^z<@6t5v7wuOTWe!R%+-gRP`*WF?gvJv}V7d-`?Uo<{rhwNq@7 z6!wSTUvV)oN=2x}(}PcJQcH*-wLa8>6|OkyJmYutR{cYw>dh!k`=LCg)53v{@vpt|F+!%UD z$batcYt7>%h&vN%5ku1d;E@M$KBbgIgZ?M99Jf(y5ygM&o^OI5nF8i!(#C#=B*lo_ z>kQ+Bqx}lMZ3qm3W$cub959TD?6{xNLm|HMZq3cwFA)_hL`ygow@hE@Oo%J!XRR9$ zf>jV&c#>nsiAH%jDTMQ?xOvXc8d})T`mI}AvjNyiy9rtwg1!Zt@x)N8pGAbb3L!mS zX10b)EWt(rq$+ik-*y!>`$rY;T-+CN-;McSmmNxtM2K#RKVQYbD0r+^8s_a0dwO* z-#$rT&H^uzT&N+$V$n>8RgD;UafG=@m&f(&SwA{F^S9QVn{bcz2e6YL4U^shJ`XwM25ULE_EijU~AvpOHPBG4o zec=9-*$gx~ z!bKyQ8(*3TbvM#S-4Xr_=~=vodk^aFVTZr<&+9?5O~6m;?rYt|Ns1-0uiHX*lQkhe z;`!qJ=@*}Z7+`apJ*&yj8c;M5QtZ$}0)B9JC|yljn;3ev(~o%O`MpwUY+v|9-O!Ry zDz=h+g+S(pE1x2=_lP4)=_#;8zts1YX0?h&O~V;1E*fYQ7_pjILbkL@ zqEQ3SNi0Ls`dCHD=#%zhLtrG(jdadtmVXYd}9bDZ*gNyipRyBIHJ6Nq(``U?GC!_AI;K};QzPdK|B-G^vPts5F z)$#6BdWNO?ESyBV!#y7DUg>4yB;tQ^`@=qVDsP$!$Wt9Kh>H;z7b_o_XyGtD2F2d4(Sxi4DuaFr6~W7 zdl#YnA<7Xbk3`ywvJ81PQYOkfkpBZ|3CgD?K(`NxoX12bm7K?kVUQlUW%=Ypj+GJZ z&}i%3XEO9CBEj2^Lad^On9+XQ!m8y3l3wStpZ&(l(cW|U>V3V>?iW6TnPBg8MSX}7Sx3pH^gV2 zyKpo;qHlqMoWRAN6Zo3_HBM{|H;}hYv6InA-%jV6C^kzl%O+s64%0bZzcYT|*9f9< zdf^0S3D1p9@n@I3HXYoPUaE0zbKe5X*{Fi3w z?rq#*>@=@&nYjBnvyJeaJ&N*^sNDVNLW6h=~iJVgsK=5?7DS&xJ^JDE+?n%B|plJ)Z0d0)< zzLwS6z6C;liooiZ&2JFks%X*v&>SF!gr z1!g%`H1h7#RC?EG`h@wy(cb5&)OVhKXO?2`#G6#)M14)8zG>dr`$VM>Y8NVYjV zUu(d|9tz?t_{ZB!h~|Q)KLhP2BJJoo#Yb!;r?{W*6qi|}A+h(I}-)VT_G+%#bb$RHFXmXw>N#7P1y@vKq`&8ZOUKqyXj#<1Q;C%-moI9WP z;h!Mt^C7r;32##SdCF}4u&f0siPXYgOd*9-Xz&@w6q#p6$pFh0+8u!B$4-Sz` zaR{w>mu6Bm!5|iErDy&EgOGno=0IKNUFG(tu*%^R3zll$ISBF20m;cK_xG-H$uRLS z_@`vw)Eur=(-odH73&V`JL#_V4eWG;S#ulqTktoG6~43=p3!YG=A7zN(|IbK;5u^n zVH6k!pBIe`J~tS64ltZxQSxFfb|6D+^bQyZM>FQd#LpN#Yd%88@l!v|>{$`Qy% zB0Yk#40$+`3S|rO{YZD@4#%g#M_pJkVO6XLoAGewQa5_AnPnTt!OAS8Pzo&qQ3;_6UNDD1BZBZ4 z)V$mbUeN6Q;2fpFXA+@^!ff&0(n;9!$m@r2{jt6`#7#Xnk&7}E>7eZgZDiG;jk@MD zj{++r^w1qHn3{jxB;I}#6vj=%F>o$ea4sgB;XPOb2r^O5LQ?2K27O@*{dOiBLkkt4 zp_DA)&JjIR>}Qaysrhs>(R^62k@RhxaX+|)U1q`~FL&;3J|!MBVrR7gadOGJlhp}$ zUR*yy%`Y?y_(0SN1B6Wh;()jI>!RS5Oui5D{-HI9kc&}F5%M+i%4SpG06Q=dAv-3m zabs|)t{FOm@_nB)3j!s!fTlMBO2KnJQORzTCMK$`Wvz!(po6B0#{j_^_hh7HiCBD3-+C$aj&)7zAmr;kJ!F1c;c z&HQZapE(XiK8^$7V&vKGf=Y1r3XBVeI*b#vps=2L<}am-mS{l`PYGN97xKDtjB6}QycR_ZrM+vhoP|NkVH*R8)*>0BT}Av zrJ>B}`I-_%eDbDNC z8d)K{5CDQM9PMsdbp+2yJP;rj~?c}Zv@w=)g8rUe(H|B=i ztVI8yDRXn(M)^Cn;SX_x;H?6qoefV#i3DB>9Ma+ti+HEPm;#zlVVDcPY+#|;aYCoQ zG1Q#OK_fnZ9V)D6$2*z6M$;Ew&S&HT{lwW<{#l>No~SBu@vYnAe$4 za<$yc@B}8WA4OKk#0~M0=ZL<;{oE#QzwQwmPG1K8M9!S&R&jw`HoemTo@bA?#8!uZ zcZ+$zZmS7+Bw$w*P~yP%6b(w)SxvqsAY3l16Y{*MK7nWi2>C$N3FYD@xhPiJVDy*3*B6{|2~Rs22kZ0tOc3!@%BX?aw_-ImkpaYqgh$Ok_vV zXWR8R@8RGK1_#IQE)I?d_fvw4(}Vj-!1LUFh3re>x6cqPsceZuXdDV@ozRfs6!LBn zkD1v7*q35vMDnMcm_K%Z*r4Hkwgu(WS!4w&DVamI9$FO)S_ZO0RnShc_OK=f(E|c3 zt84Mq$=)C~jkw>lGo++7n){S!ZrBCbm)=Yk;g?-xcb&K5pX4zvoQihJejW>VH-mH@p+-@7NBZMOXiUoP66K`cH`Su zOrZXzEvRU-=A>N`H^HVTmKV(lmudSH1L~PU!-t)tFxkSaVk3igF3~CL zmT<6USuEzKh;@Lopm*K{#)sWS6sZk@1{C2`VI?vG_^f|T{T<|{FJ8Gbd#}|#gs(@w zi3&3gsBTfO5=7QIpTQ{J3VufajBga#?$s0zSgl{}tIKq^x#HX`blBLKL$-$r9I*WG z3_J-?&|)$OBTGr0fREci>x7ss)1yycVPmFv+bT&tD^jR(n;MkwvXJ{&V0aOtv; z?_k}-gV93Bid78`W+*!bd%AW#aadsjQ{0A@j>F;+H|%b-?qWNJ4?=5}m8i}* z(kUj>ql1Ndx95pMtZ5ZX< z0$tH8k6dN)bm)m15Em;E_|HhlAL9`l8L8h=;8_WfLk$BXJlLOkFm&(-q0h1K`pTP2o#v*MwPK}q$OJFM@ik1}a z-~>tAbaQHFY>ms$G>P6OdB)tpz4mSew&foyXHH>Y+RJVs`4MD9V}tAR9AyuCN? z=Sj$C7V2i!d3ZlWk{NhVzBAq!NO2_v#g!)60)Z)Q1Ez$%37AqY_!9?O$P zLGnp<5DA{J8}dAH{FgRAD`txvPUX; z9umnJP8oDn)HqY6MJM2!4%$pL%*|b%g zb(5;a=+S4jJF&;S?w-ng>{c5jw^XxDM+xsLio~HY?8EL?!=J#ODU~1&6r>IvCaL9% zW`X1pZ8UZZGGF}+`{8T7uX7?~vFKZ|LR+L;4DF0^-C@dM`Pg)hcqtuQt_!Y}HH+9S znuWC|A&U*TrJ83wO3s3qYUoPUZ{`-(mP1DQ4JWl~bVLt_a7orvKCmz9B`N;d(Ie+(hVQZMlkWC@?;_lRQRE+J zQVP?+SD1e;O}7b_!a^AfpU2`lcx{b`Ok&h8&;pa|UX7+c&f#>&9qyz41pKtl`zYOcpZ-4I9g{nU(*1I%eyFc5r863JuS7-b z??ltUk*StXl(!<^g_MeN z3a)FAddsID>wiZ+y+R84G`#!WE1$k0^`o>Sky6WcD5;zp`(lAVbnJU%)UkK*!ppoe z>a#sE>XP6>q8r5U&5%(mC^!6W8TD1KjGD9}GHOr*R7U-tS4RD{Pe$Eu&~eT5+Tw^U zy7{&6ECPP={4=1nrk|wiHr%A(`fhu)Hi-+}v0Zc3C$FCPCwcW#kXMJ+5$++CS0hHe zl4^YP$gAhrLa4@vnirTo(&}YiX>}>tElop=9`D;zZL-3Df;T?Ih<&Ya*Po=+pHeCH zba2QCrSg$i(su;-kw-rLvALg5K0V{CtT@!NS;~D+c>M|@>r;3n)Wyz&lxjR^P*^sW z%PiZZ{@;@k{!S&=W%i@aJF@(pW?5m5le|r$Fi}Z1naL3NiewV+@Q!;+vJZfFyb8Qy z!#%v?d>>s&p0&uS_zR9A%P(#9$g}r&<=MI;I>@sVpois^$Nq`?{^(uuY#EVfkN)4~ z*?r8iW&zH{8c11XKAH9>e<9PB-QmL56G?-K4>N;G(HsSA)bPX2`!Ngs4?(I?Lu8%3 zrP_ga@!;>4X&-{E*HMR_dUj$7EgclRYqVCft6cL4m1}!B>Qu75*en|M1$O*?(5R47 zdCrpBfMx;vhGvZyTAwG-s`i{RrJ#A=0KC?~?kJoKE!?iT0xtU_u+1fW_NR3^yLhCU zPceUSm#q7QSJr)~m#q7&bn@9oz2hEA>3u5e?%|RXSvR4QAnVTWp_Dwb?%|MiTf#k( zZVmSSO_Zl8E`C}khpeF4REs@qZd9$l*0+ZpZM&m6k`C?Ph_Z7I8Mx4D{y!!H?RI)U zJZBg0!V`Ade)dBDt2TvKKJZH~-s)P)Tm2j>1MsE{wJ3~a6%gFvX(w4N9vu#5_;DNI z!Is;|d@0}`L82sWvhI?DhnoL)IrzrAVO5lWBz=%lTMK;L>PP8Gb+1gkhgYq3{MD*r_@mv>uc(Jq z99-&Wyqx-G@PEg{8xnzwDJ{24$9bjBpE-#<{_S2*f~L4vLeB87dnM!psf0Z72>Cv# zHfy*EKAK2$4v#c{jYEU8GVsVUeBpUfOZCfqU-)0GN2UGGlDjV3-*hg-^;e=Y^$UI1 z%Ui)!jl9EEU9B5n_{rAjQ1p@!lY6JMtUmIHQwnQWB9;H*eX?5;nLJrp;wz$2qyIws zzMD$l!!L?P1^ik19^9KJ9p)r_V%zE-KCys*q?PcAcL(?Ii3R+U)+E%u72Lxo7VvXh z6X{vs!zaf1-#U`w1S5N443k?EaBm(Y;R(Kxr?j@ZB&{Cqac}$~w)H-=tqtytKMZaq zyyUWZupgN$ft?%t&&-lA3sgep_#n_aNY4xgk9Z(#b|avZiSkizc`vS=L%9<5Z=n1c z$}gh44&^eGIg}qkc_+%}k)A;Ln{e3JAx%d48PxrXGz{e>$a9fKqP!K?cOl)Ok+#Fu zZhL4Uc*)q!YAo=b!UkqhO3BaIhia@vKs!<#Im99>03R8;okYV^SrFmTSF;mNvPWNS zHvBO6=&OzO%EcG<-~weH3h6MVkO&=(N&W2A$MjzBA4kSP*#7qqjzQ%1O4sVn4__)x3q$Nl%(RvTIdkxj>99S=o`~Vs(A>|R+xuR*0B$3nU&T#;E zvN+xjtCl-_TPcY|NiA>(m`|lw-$N5kG0VLApLg_e@^H=vKwlI5N_d1JRM9*yFHLV2 zTPi>m^)oUzXPBebR(NP4RYdh@P7t-iwgo5Z=g|8SF?ooTC64@}Hfas0Ar+`0)!fR0 zqXHiVS_5q|&?zbtV*Y?0^7GI`?IyA1-^~KQnRn=+{C);H--ba>oPXu1#(Iq#`pKW^q z>uYY*3;GwlYmw!j=zc09oqO9m>VJSL>d`_SdG;Co6ZcR>J1JE}qzXNHs6+>>H&x`3 z3jf0)wk!;1o9s`8Km#mG7-Dc?hldV)!C*rgch(^(j>k9m^sU^!xfgZx8zgj|Z=PX4 zWYp{K?2=>@JMFVEig{79^s{}VP$0Slu9d*59D01B_=nCFYBp8ZMhqMvu7f5orI(Hp zYA5oBL(6S(_*;U#5Jg}~5_!nrpl1*4Z6u;y^ZJj(Oy|;wBb8E z!=uwR-N|wvgPQZ`^}s$-S87Xl#?hT{xIWI;$BHhu>$NVj!{r4J^HE4F|9%&tkY0(3 z@li-DzppEr?yf!Y23fwiD-!Jpbrk7)=9^tZP)DevA-=ko;M?GEhKD|C83P^MbnuD> zKrg*N_&!Kyr@{A181}w?u-8FSp?s<@>X9zvI;lU4)PnL3)bU6sQJ##t=aIfa`3cmS zkhY`T4|Op}z3HQAKKe*a=%c^X-@PIA$kqsbMCc+9g>*M{B)f|`I_#y6Y&|=oPlMM( z9g#h8?b^h zqCZheA5%(+^HNIXUR?2jk5W41(}p}~cz|m1PW@i-Cr#e%PK9Mrd70D?S3S)qE)RFT4KpipscWoZ(=)JqCqmnz+ zQ8)JI-rBxDn(xu}{XbAgVoDwTg1!8^UK+oDMIHGxe!bMupkCC`2=n5~|4tuW`X9A^ zkKV2ITf}N5kOXAkLme$OPlQ)r$Xb;Bxo}v$FRL|2ys3G%7XD*Ft*to&T5aYhlvc|( zEv^)rWT1^g3qrV^8YlKHLKEd_(!CnMADB$KW4-iqKK4>YC3jIp_n*D2zjO~(G~zEb zfW1`FJsQ9xC{=Wf>i-g|=vANo??YbtC{H6dJZ}3Md)VBl)B3M{dss9q5hBViQte+g zf05EeKlHk1m+i9CLv3vJQAAVBJ=!Kr^ClCab-uns6Ita(qI*ev20ROTJna~{IuuvI zEudW1oV%!?Fa8hOz;E0|1>L@K2p*(*WAuxF(QmWAjj_#(+M$2jH?|MjJw2ZTI>}m| zDE-@ip^}K6@OjWCgg%-~+IaP3=lZB5=0??@bb9XS4)@SW6MIoNJsL6$Ke%-hVoON^ z`xZ@U$vqNkCA#4oTCSE30k$xNLd%qv-%CeR3TcOruP63s6f^uSw@0H`LFuI^ zs!==!^b(=x&IdT!0r&-cyC@OHPWy{$L>Lv&U7< zq ze-UXq%D*C!vp#}5lKyttI&DBhW?9K&@y}_=oeA)Zp}lr-@C&`;~5J7!tdQN z+rD>4jFuLD>kcZbg$}Z6bP&p6HGOu7Aia}VgiQjOzg29R)tD)p=Z-CbwS3bSp|~EA zJX4tAGi+~bGV12JMT)ubW3yRv6Fy+mupjQ$_|-`*d(nrv?l_eNF+%W6li&>WPKCr< zkpz(UUF~xj=ea(+dU~3eh2RsQL1ITU@y|mS?0a`YBs(ai;7yGQ@~IQVzEdStiR;DI zDnvaHsTiA7m6QI6mk#M`z2h;k%G96QxkxSYCXtYMHHWH+0X*nI|_I=k;Eq0*|A3%@ki zGZoIjoiZ+<7&MYF3Q{IEDatUx>2^UjRlQ}3gsBHF;X@>{zQTqh-pKtPe}PfcUjiL3 z+&0X}=HJ{bDE!bZDiQHP?H@w3(FB)8^{&(1YG_{_0AI4+^;tKpAZ3plk8YmTxLL87 z`;@B=Kfw**1en{GL@8QXeVR^i=7uZVonO9GJ4t&$r>KkG%ofSveP}ddBmM!alI}zr zt>evioBYJTI)#?yn?nqqn)%OpV$X$g!_$XnY$PjQg62@;D!{;Y(_NS}^Xz<-c2ZBJQk<{GTKA#|4z@ipxaU}p$} zPS-3(Dfa;l{fAXR`26&dd)-ED#m< zl)>fN(Uxdn6Q{r{@@>~hc$b~kqJR3-4OX}ge%M%Ju_n|$&$w~3MH6)9)aF8se;xbk z!g4{A8Lq*=hZ6Nh$I=^wU(Z>usoi5j!?yZ+V_H#b3#XtO|pi^8=TOi?oPad-VKNEMGM}k z!uv@dZ;$t^oxxn`tk=s*Gd5@iLz#m2(UvtUBkMF zN5rdkxi#z6bw)v^(z(6b{mn|59PuWF1^p}oIIAuc+%``v0yQr*@6i$) z%854Cs+@?`s9=U0?Nx5<*m3`|tx>Usf4I76#A}A{nS>%z^} z%{Bw8%E$N1U+&k$G8x(dZZ^n{s2|;MR4(Og70JM8lMPFqRc^WJMulfw#D|p768tI? z_lA9zQ^rMdZLSmD<<35c^V;S*)_obY9up|Qs&92&MRctD0m-ViiO!N&Cm7lB0`1nY zEsL1Ab2hF?TZ)_aEDw!Av_lRloU7%}x6xRg!@%B)W}%xR!R4aj;f6 z{;*-@;58d@1Soo)Fgw$=$CjsL;mZUKKrA;scGC-X8TPq0#LGSJWZ(H2 z)PkrC)}PDSci2MSRoP1B0lk3^(fT9bIpABq6A(S-v_m-bD@Q2cnZU9Iu)GKpIG$(@7hw4gli-+PqQocV+Nc^ z;qdVvghEq_iILmI#)F!bMybsbA&3*6gP&uAFgehMh&}P2RTF=C^9=5vq#1joquSdI*^+K)$5m3l4Lsz2yY=bbGc!x`e`Q0=%dbt6Z-n; zKDh|?coWbj=mYU|vHp4VUxohP@J35wsx`Q7#&v=dGcnN3+=H|&udGcg=tQ<=*OZR3Hq))g{n!-$ggX0Mu zcFY`YKYmc#{n2`A;nk1t-!?Hy$oY>Tb|*gr=Tvdwt32-@-r+Oxo)w*m<%^)bPHSh? zx@46Itm}+`jz%cv^}GapMx>WP!z_4`&=BslEt)|YQb>H)YY_)f9RZ&Nw1jxdLg;>m z!RN)ol^VCoz?N@*pzjR$x`#*R`S~v(;^BktSZ10|X#2zUZMV)Hn?JpxPyH36%1HK6 z75Z|jJAu=c?|~(ISoIs4W_Uc0^f+wb5jx13h6S|`z5zAMj4C0 zDeI`WU`X~iy$fu`jk7eGo?*<5e6t9cHv@~EJopq%C& zs=iF>9)DRQv;FG38rEHp@~(&LN%TdP2jl)3QSq8w)-Gw$A1)bWubE|{`f2b}UC@P@ zDEl$}3-2i&?K{QSnKQYe^c1&e1f|fimo+;5jxaIza}zm9f~Z=QEQKzle?ppDwDPun zVk8--39%~SbrSk&mrYE<tx*nPesnP4SeR)6PJG{kJx`W<(yK_aoG(m)TApNW7apIW0Tm-mEQubYD{Qv?J z&$<1Z#KL8{MGup&e$14X!zL3wJpvc6kgo%Y@smeh$^c}-i#D0vsC+%(QPq}MA#TnW z`Zo#1I`?BcmpI9+9%$`VhqxgdTIL+7Z1xWfv(4w8ogr=7Bz+b$ialct{VwCAG2@M8 z8nNv`%$)~f0=h6$4CA8eAQgr()5eKjz}EjReJ>3frLBSw9B|{oRx#;I~_2GSMCQK^yQ!LCTn7n zjfweqpd?|WEgZXL6!(rM#6}?ImVE}D#d)1%?rS<@?&{4)PH9XOYz-7xp>doZbN@9w zQU7Z92c2r-CPuD_Fl6`TGrEoC5)M{`uYK;6jkscy#eCx&PiJ;R%Tq_-s}22OqAxZG zjpE&sc&RN8F`7QLvB`j!_}lg}$4cWaO_fbHMi$-djHkU(cCG{7{CX=>{lzH6U_|m@!AYX#?9LgN21Fn*?5;^v;+n{Iv ziFA0R1TM&6KZSBG@>Jx*V1rcxz23$g&}0H3Qv{lKKGJh2k3>3|3mG{J-8cAkTaCOQ z^286;PhX#r2Rit-%$4Pj(HUH$C$TIC8f!DNGFeDK1{k|tLpq;9beEOoD`<<=dgh)M z0iBQ27E5W1m3q-VEjl|Mr7a$$Egsgh_q6!E!$4ciq%D@|1^2YL(6NZN;Ao3Xz4)FM zr#t4+7E@@8IeO_mEh;)@&=%upiwwQ&o)-H%INBnSw$SSR?rHIMhnlvCr7b4w<@dCB zxnlxt5lLH&(<|<2@oYyjZ83nh7_C>{(_%$O!t@a{p4YyhEqQ!DyoUban$hv@!{o$G zRI7OFNv668aPZ*>zy|VC60*2X->(h|x@%tahS0Ux2yaZ_zk^#RH(5?pb?5|w{CY+4x zKS9UWYeT0GFv@aI=jwBrTc%ZlTg>WD8~g?AE#|4Z<Rl&-clFbMs*|DaL)0ntWLH$er?sDvJVAi?-*e#6NJd9*o1LEfbuO6$;VtIr zZ{Y8p&>GwE?wz=o`2Z9q?9Q2_aBy!fw+qWK7l^Ox1`QBEbPD1poV#>Y$S2+xASf}8 z1}$|1UjLQVf@n5ckUZZVt^VEVsdscgY7}#UqoQpAqhf6JXe*r3?Yht{9~FitNcmx- zhR>fnV_Mqe31b+~9p83)aL!oH{qb_+7+BP`+E_%Gc-MH##tgmb3@c}c@=hl9I(=HV z>w|7F@h>{m;bhvyw|;|UJeIrUO6-Eq7H_!&@rizPjtD2MYLS1?_7ZT~@0>4bQmSF` zG4$UkZKb8pP=c>O)K#MdPsb=#;*JwevGzm6q8g9LyTTkL7m;|ZJeowzVe>$z9Y%Dw zNMkH`EAMrUuh?VUkJ8?*pb8`W($|EK|M-`j-&FIhG{FE)o7N+?=Jx9LoQb)Ew05Tr@seUo_Ui`J$(qEXqwqAZELkCgC(JTD-7j4` zhx)Q&Y<`vQ+=W^mG0hN>`ojITha>juuAE~au~mbH84nzoM88=7*d3nrj*YRt$c0bk z{-a4QtIVC_9-qiIeZ>}PPS)v-?p)q=4d>~H_G7uirmqC^aJ4=AL1ViyxvI+8mK$!c zIZxykY5qw^Q{*gx<_`nkgL9o?w2i17 zSji?Y)wXB<;9L*yAmePc;K`C}Nj3?ntE%iUV4W|ye{fGKi{_SKrU|9XPEtl6U8(1U z?V_7lb23{dPhy(I^7a$COVEBwE8dXECYQpSwG4b4;2xQ#oFYO zwvxX!tv6OGqknLZuX#Q@6yGbNM%XU6IWb!~QAv1FpbXxJ?Sr0M>{j}*lX#Z~J-%sw zKKDd!lgr_L*LeU~g^-VK%|k4B4?PiQem8>!rxH>9^1}^BoqK82K-qtZ8o1SL&A5L# ziQX=Z6eS6VuUjswLwsJSx=EW;6w>DLepT5K^@THMwQMlFs7=hePI-YdZBOTr>nvK0 z_Y)e_w|{?%+*OsmB||WXL~0iW$r8^S)-1=|Fro>-!t;M@P$Y$G*RNE-lR!o8V#I;_ z%ALpqiQyy6V&L*p^Zm=2k^csrbaf9q7VpafZ3;fmd3UI4U3L&WiU$Qv$o|8nXj_-7 zE}xJqn(!51sL8e54UBipen%ffEzwL-)X`m{kvBir2_S@6omMptsz zug)JEWGRUDS%ZjttVigOcT&Iwm3dmv1`;VoAgTlM)-KJyH^oZ=_Hw|)oMzI$7 zW?nmf3ki2#K;zNrIl-avfLt=8XI!frQ*&8R+k&!b+`8N${4=d=)HIIRzPtjhvcdfC zT|#aey!;N~bJ_^x6D!7>E14*8LR7H*UVhy%;(z?^d*R2~1Lbd+Vtmp6D3tVyz{uR( zM%%4(@UGW8H4#BvW%hN~bDfpBW=d=AFfHWHxFQ=)s%e>EXR{o5# z(I8=BTLsMNha}8Nq@765Aa|`xpLdJ1NVyZM}eo0oFTK+c%>1s z0Y7sx80XLM^+fnZCU9ThDZAuO*!L<2eo?`{(cL6p`$LU*a-;4Tg{ z`W39f?k+2A#C~0ly(BEL(RH=c6U*UE^ZPUIv%a7WEfhD87llFF-Iz~ce7dQBp^6{c zuE_73ui_eAw$6W~i<>jq5JVLU}hL8B4RWXFSBh%{{{RzU7no~5el)-@~+VxQcjtlh*Cnw zc&#|`x~pG@kn%}Jm`8((EO)QZm&-49{%-9`1O&a>mE)bu(5^>OYIFs4 z&CP(!GMLP{eYV8v{a)}&5PL*w9p+?HesE?*BysSDHc`p3L|+LpJHx6|`8_le-E+3# zm{T^g4`77slDA!tQaFjgY~4Ua`$sNZbZg7x&ha^f12X4GIQGFH;kOO`&qM(3CYAN) zj&b5$6YH7kkx>$+QYB&dArj`XNC}gTMELcw$W4nu>mZT*S$B6gp^Xzz9={ZH?GpG9 zX%R5r{4QWRZVH&kkftq?FoTgUquqjq5+(sD^j8omSV!+d(k%*P#}UlxJrf(9PH2H0 z-L8hVw215WWt_-q1S}BGsw*9^jxA?~wrdZfw7tAt`%ecmOt|AFyfH1$*;0|^n;ZYm zhv?k+b!L(|3?Xw^JX>fT=7`D}RxB)h%NY9vVmi0wJ|VPlJOvU6SU(f*@_I_PVR2O=u;& z^C>McN5JO*hRlw&yR?6ZwMpDmZX`IycGn~l6A-!9*D<6iKcu9X50 z24sl<1rA3l=f7K&w2TvSe{)Bz`pmJ63)p!PUv&xQ>-n;FZGhvXk&Iu3(HFO7dq-al z4?)4ZA|OR4;}5PSqff`|M_}}~G5XIOw_R7=PlJm(1%7=-!b19m(g}`e?gWz7d3dmd zIRTpXyJi6cYf~mQ6Y;%}2uy5(onRi~$nM|;4F5sIjEGrzh<~*~`}^Zt%flh9J=?$} zHa$#ufY)97I!cU~N65jhyWZ*e{c$GY4|{NW2zF-dNQmu4+H8Xd+#p2mY^M=!_dg!S zUv(o6ee|J+Q_59bjPWtxO&dCx1h-uXDKY5s1>n^T#QBH!p9Fn+;|~Fiak~KZu&?ZJ^Uev_=Mi1jeb$Mn-u%V3jhq2g*V z3N;Z*E2z>!1;(a;&rA3uAs%xIA@RpZC57>LX9mVc?#pVQUrxpsh4C#eC;Ghtn;L!i zyuC^K%J)j_%QfwJPBJnQ5j996tzY0B*;RWYMs}sw$cFny7UTZWdCTpvp*vGNi~-&nrTO=J$&U9YthNZH(;z%e75?c+cGY`*84g6iLJ z$=#wu8d?R8+9fwX=Dk}xA6~EB3+em>%6YKBx2upns0p&MQS+`cLzv-Wd)ie-#l*Vo z1Zz?Ad!b8va?E<|JBCZ{6Aub^zM#!Qyplx`xdvvq8nFgc(9Z2n+GEHzkbO&RZgD*h z=~)?Y69#tI;Rjk=f$ao$Q}at8U5MFR**q!`G&cAH4DbhnOAwjFO!FKLJOk(wF{WFH z$u6Pz?DJ+d*W$|S9A}(*#hr35_ zdA@tJ>hHP--J=sDs)NyccuqsF-ZzD7;o}5RQq?$33W1lNY@QuhXD@WKD9sJLfRX?u zec%r$2~o;~9$azW;pP>LEWhSxXzb~8>f4cmnj67_Q)=RM{gf?yZ4fse&pu!tjrr{| zC&#LJt9jAdB-CxmW1`BPB;xrkm#KB7k)0?kW~0&#zv28zGpsECHT?p`EyIlye0#tX zc@yalkY~6TLk6qcW$FISNxo3VnVZIEa`>?1oN}WeAzAx*gE*)O-(|@;Cff5=$QK!J zXQDrEkR>0=X6_R=tC-saOyo|bi;9Is>$F`ib$42XtU5MFWfM2A z5Qv)%EX%iaS7CK6M!)wu5s}hfieCeb?U|x@HCA?uOWkqYd%eIZDXQb-?_76%*UA9i zzHTM-P#-(N!#-~%JJG4ugBikNqP?@lK%ThP8OAlZu5>MgzBQR2-reN915X}k+GAUt zD=lE+-m(4AAl-P;F`K*QYNyh)8k>lF5E6q(;Fc{eF{tq)7e(3;;kO`jZgJge|KHaJ zY!ORI-~QhEvUdcdiPxX`b)3=)2vh+AXaCS3k9-BV@=?IDUuBZEgxSu86s!&lc#DaY zyz?^m8yA$1wlQcsf82g}zRs8BZ{xONG{FUa+r-=YKreDq$$Of0G)@r{Ij~X)Jq0!? z&W;^4D$O0KVumlWU2GVa1V0GM5bZ9l*b0vh3aN!e0ArKI@L7EcF<4Xbv$=qGBpiI% z;dzL+RYTzSKhTf&d|3&0){xc!C+KJSw+((33lJmrH*O==jN%tLG~TA1dC(or$i_0U zY2Z#j)`iGNf&~o%;d`1v)nsK0nixNl7DZfzc9G(jnVih}6L%3Z+}ZdWQ-+>mUpr{O zvs>)e2#MuzA{+UZ)02C~^+~UB722Df#4{fgDb(_SjRkm8O8&)$fJN6`AG@zPJkKXj zC+|q8H#?KGGo52&=i3*pO~J|;yOD_sbu3;BPjA2|f=XqU&^RS{q5^)Z0{{AxKZ;QL zw~s;*!1RS=y5kD@+j=Dwe{a*jH?M@C%)?iUsXwu~@thz3z*(>g=@F#Kz(Z5!0tdkL zgMRQ^2Ybd`q*SE+vn9+jCtS25T}N6`Ct!X?4s2=oI_>9IremdtZ(OuihyMO%W};4B zS+sU6%7rL@cqO1o8MJ~E7hZGi>6Br=gXgnSrs*@GyfDbhG>O8n+XY}o697F+(hv<< znR$%h*d@(;Zhv zG!VvgZsY{uk=V5hfq$HCcu(`7TXu3_wYBZFcHlLWkPa8N<+TxAr%Q;FJ&jw$)oGV$ z?XKeuKRP`l^Nbdex-hOVTlgSReI_(?nfM7dS<*b?dpPR`RxXWbK{N~E0s0P0H1wh zMWadNn_YPN7--cmBM=POR%Wi&0m4(&{NcQCE{NZaRaQ|=bQ zf4R(xUMc)`i;@W@CEZcS4TdMR1?~w9^vpYdVyjD*uO;t8jk}?(cT}Qe|D6h8}gheyXypofdew!sRTX!7wGy+XmLrcjhJwr<)QF@G)hNEPpr5Kb9v@`^z zCA1Wd(tKL#i(V7V%4!;ozXhh`ILz3(q_`;BR|(oB(snFL3AEHvdC46^ORmaA^xo-a za&MYB87F3w$%4BHj!Sy)sI;zwM=SfC`CLRt``|+Sn?wFAoI(HU7cLB8#>Nf8n^WQ> z^v(aSY{se5?fM)~Snh+8XnOzPDEtd2f1>))zrj&a0d%%XD=*W#4p#m~^M6+UO7p#y zztDVFWj)O;m6vF~qmuNpu<|1P^=9QyG=Ht~0?l8kJWuny$~u~Fpsk_jr@efx zaxuo2=^NiH+Q0Of_{WhyGd1+@Lo`=cETj3PilsCkU$KPdDHV%po>;Mn<_Q%GX&zgVN%NSB zztLP(v4G|g6%W!ptYSXRLo4RdJg8zW&6O24*EgNV8^N#nO~4qDVv*J$rKf}62%h0; zq|3DeW)bq|uLzjZUj$4h%5#y%BN4u$04WG5AJ?8kT81M6r zAB+Y0MqHnZ{0sb^j655^HOP~YQjx|Yxgo2M$Y7rEXn-;N!p^3ZOw2HDUPa&fHO90E z);5TLu)S#|J64%;Orxkfv~tLRu!YxLm)cGk(*_HZe?NE4RoB+w+`sag>-)CYoNGAO zzi(iK6Uz@6TU_$CSm;2z)z@5KR$g;`?)z0!S@f%z5v2PW8Q3C(@ERybdiXL*?)VIr zJ3j3Nt*E)L@Mam2$T3G^Gl|Vi6vr69bbrPIUt)}$&9(pcLm83*V#o@lU&qdQ%3$R7 z>yH{>VX^s`If#F;mGC)I%|fGzOKV{?A$*WfU{Ld;%)6<)5FDW0?b++JZHAqIskST) z>|4HiDwFHOKiuUmmq%uDA$)Mho9RUEApvJK*tmpS=oSQxc893)MdI(_>2nGx7l>NV z64^j>e6oG!F(QS&AUXHFn)}UlsG~hMt^DO_vZ$A#6|-K;8cjx)Khv3){=Apk|Iz)~ z=sR-!t0s4@^p@lAA7jS&H$Cq^16|ec?L9pUgHAxR{Tt`tjyk`S$u}@&lYrRz(rgKY2%#k)*Lo*eD-N$WmX7eq4oyR=@9Mu zETML}Zemt+-NfA4+&Y6jY&lnci$uX#945SFT3$sWHM(xKy-a!EPaSE`nXOxAv>MlE zSLN#M7Z|nv26qDb?Eh*I1&HhWa=V?c(Q6l&6FHIG^SQINRap^Qo2#^GUG8wMD#tc^ zO-?FmZLWVdC8f9LuG3BcmfMb}8DP_9H-x~Z%w938W!h6Kq7iMZWPNs<_B}UxD1^#Kj?W$ zJ@jV6PuQQnhD=o>VLm}xf)oh-_b^-^KUKnXsiE_Q1pVt-Y?LNL1jrUPhcQH2&cuuD z>Z>Fsfrt0F(moOVit{;4T()h(%+wjFvtESe*#<52Nlb*7mTG4ZrNm`-=LpyAD^G=F zE(nm28sBakcuYXNI^&5%p4DpKsEIfi#IaFCU!l<+Ts|DnJ(tDA#QG$@VMJS@mmE6r zCt}&)epA5x>Ku~MCmj9AA~rPw?sIs`mX*osPlHCwlzj#5dYOXs=7bHu{o=r(mNj>e zS2X=wzSun>D1_(mHLil%5~;s*24EGQ&nj|WbzSPr$KSXv&s&)4VVDycQri>>b6n`r zt1Lr#FOmr<;vDvI*Z@4QHDLcKaF-Z~-NiN6>nEU#1)WNdO>937y!&Q>44jdmFmOtK z?+k^1WGN@BevlK|2B7A*PF(~d@xjCQ16o-%XgQO}7LNKKJBbBfD7dl8!u#o!#4?d> zAg-JyR}`VVOz2;z!xjJCLR$ptKk0lRVySje(fyG5oaoHsV#9uS?FE0G>`3`$zv3k9 zUeg+%D=+8vbE)^S^)ffRo^Z(bb|QANpGga!HhwMk{R2ithZRGse^LlPw2ko5)%-X! z@!_TB6U<7QN192*1U28!JSut+X*&@*{{ovUyird4UwU=dGtB>wx^DrCs#^PBd(Yl; z2SzX*2E+kGxv7Zv`!EbUE*55)rj?XkC_8Cd9kNag7cZ5k0}LuKcqyx+k|Ekfyfm1d z(@kq8>q{|@l*%NdHUsF4pz!~#J%E=y-*>*}`9IJ9`Jc{q?^&$9_PW07UGMvQ-xoAf zo-ItsjT4gUE_$0mR|x#bNlxq$x^v0MR!0O%A@Is}SL^Iq-(Bur%CC^B7k>_g1nVS=hUyCsWM82BVJIq&Tc=>V-!x0yn=tjb=kpgE4Lp*RDbR(hAjcB18$wFLd zDRh*!t}SWl&|XT9Q(C$c`fJX#CGF%fRpn$sT}{XO(D$YcRn(x0m#`Ne>zJ^QB*vUL z<>N}7sUv_;VdPg#Qy|?yoyT-I23fgryd^9u+?s)JGGlN3Dvdx+ZKk`uMP1C4Oy5v4 z`g?9HiO%%JB+cy6DjA}~#kmsVzT*3}c|>$r&#zYBPxz(l`Q`E*Ze9=_+Vks-?_l#@ z=&#Ouf9dKiM+v)PbqV$FlkOxj)y@&Zc4vS6dFb{Fg@!sNn$KC8lbS=vMg?4!8lI01 z5qyyXi$bq5yg>8Q;QI5k9wZJdmr^N zd)|Ahvsl=?I~*2IkAza3Rlt+dra6!zl^Qv$op%I{ozlj~ge{&Vew;6)DWcuH_@YCB z2n+tdm!dopy#~9y?*NCEe$ts+S1jDw`qb!#*2R)nB7lOOOoo5kljppX=zRyEktM~r zC|!>bl+`49Ap8ugsz&ETW2chmltBMbou;+z_bdp4-BAqiltMqp(5C&K5kVSzDRdH$ z_5@N1i$4!A2*@+k{v7;77=m1m)y5~0i!_iJ`o=^%O_e!Rkp99OZNlW7EKqi8>!_*= z%S)|`&JDv|RUhMKd67H&Ta26I+nh_%F5t}tLH9Y>QE&Rl%uzWT@nyB!1|1ar?ua0{ z9XN>ZZcMrC;KXnK0~UTHI?c_hC~;Fw6s(F3S90sB@K%~z!eh`+2n~?fj zx7)eoPP!*#yT63h(w9Sbv<|szG4x|U)+{$s{l3H!ume#@#?=V25;Bxx2N7L&3}&U| zl<%E!JgkCP%PC*=xR*^*+$(VBEMG)37REYsNvF2jIPvJ2Fk`D`+2i3A@b(s1l--gp zuSnZ!s}SU_)kKnX-dhdrETwm(C>{|LzVjM?*Lo!E1K1s{d%3X*IkcbVHzk|OuE>#tAabwNx+`L|$#SLot*;Sz zc(yN+sN#n~b`b0y&rD;yB#coL|9@vmKjtT(*=L_)MyV{2|3d!;saG6v|4`6hk9|4v zyf>%=ei9;S-+YaoE;R?*$VfJd&Ec%?x?bmjLFKry5zy8qj*ZQE*|hG;`;p~Wh(ckRG*=a3n@Rf9YCHRU$GgmtpK52tSu5dhp#3{{BC=lU>522Oq`jfw`bJGi<0s}L>7UD_%nku0or`3 zvF@)|Sk8N=0uew*sNKv)6~Vq5d6GvsF`iT6kq;vZ+1fA2ixEve?;Q$nnu=ta|0ign zSv5v9IY=zGzxd4o;x~h8MQwDH@|JQA^p(T*m9yK-M$%FOX(_>;X6O#o7n||z`04F; z1HUyd$B8s~VqETQpJs}Gj;Tf57S$0O+>D4Qnk>#aWh8CU4?bE)RVA(E$btr-Z#8I{ zL~Pl?=C?e`z}JLNJxhZ~>zn3NzeTtYkv0E||Gw+V`vv&~Pj&e3I5~%>UvPQI+S~kB zM-CAgbA<#mbv^I?Z@%}R=l$9lCsaAI~4EEU| zqy{EU{M4fex^x^-qbsx9i(XRZs3H-krh?6(vZ8zLU(-y>SZ%aBWEE-;i&#QbHgwPZ zX86YX47=W&;#YZmm5)+J%FCXo`88AHa^Qb5+a0MuM25(x`|?P{Jdfgcc6%YdC5uwv zoq2t~rQ+{defc>te`ZgaZ(>E!I%KyO;9Yf;4DU|q`CA0OXK0n69`Z8PI6VSTBJ zD5RIgpa>R`&xpdZFvcCkSm^TQuxc;>O@oRifnm?aP%-4Cg z&6@z9;2MD6BXC!D^5o0$@WG1fSH$A_ z8khT{JA}l{;aMwS@fRq1G?DnxuCe3ou^Ak!n1N5cGAu&|4wybCVD)0fkBqgaE+-xZ z7ri??6Oxs|R9^D>T(*fyNsiVf`$8JR+sOj2BWbcCA^4aw>M6W0b${$5RTANCSh_M> z6LMtZnf2Y?$^!!;fj<+9hxi`Iq4&>g z-Ux0d`6~PQ^Xyx=>Tn&z<-qj|E)Q`__Ha!+AvVghgw_-N=RVR;a{y=iONC3pN4bH( z>M(nVK11REi~FOYcMZje{Kez~FXA7M)QIT`qmFI%=p~%MBqSb}#s=CWW(>-rwt?Zf z66=Eo%CE$um#~KzpfBFT)CRzwdxG#Y{I}>4p#%6ycdU;SQwDTvG6QevVYNdq&_0%m z_~ZeR;J9EDO!2b6Iop7jhQA*4@0oUgzc=7sj0=2KN`GNu=ESToMVrwxX3D$!fNBoQ zz0*IF;QNXB0CJPb<|uCK=$!AopSS$zD^8jx8~ekE%v85|;anf9|0g^l4B1W+$3ho8 zL6AphyFXC>?0p*8M$IMjg5+a|Qb}TV%h6?W$gSp6RG-xxHEf#!rGDqFZaH}_Ci?Sp zk9@Z5uK7 zUfJ$H%gCwgY1!@_;%~~M%7nqN_#B)$7=91HFKm9v#FTcx0*5Vuj@nF-K|o&29J_lx zP`p%k9tke-g7?*Hur+Vu#wO;jsf)_9z)NZ}+A~22c5lPUzt!>fLsR2_hv%uyp?*IB zv>XP}DCoT+&Edd$5wS1*Dz{T}0ByZ9P?!TRIddpherGYP0D*HB zad?#XSYu`q!W;>M8z6@pYm&gr05?dN3!GPId``Ga5_H*-nVH@*)`~t1Rgqaq+p$VN z{GsFTdLk7c3ruZx%L6(kKpuYS;{O$_wt10VGDpAz)>gFX#X z*u1%aFK5LQIf6Bu?4Sv&$KC5xb@l5aBlz*np z5Pxw~f)3y9)2r|Hg@@mbuiZ_*gcJ=@)JTydg`2Y55$7JP&`+&1z3a-nL*dawg!MPO z8rJ2{h2pe39H+2=g=yL)$|YV$k@H>Htu#O$NqgmmbL^8x&k<(fZ|sx*z@7F?yW=^` z*)Z58UiJ9b>Swr%=bx5YaxQnpPEcT%TuNihaGmo07?()SZWJUX-QM%v5-T$z{dh90 zAtG@u>h_*S%Dmh`Pf^(t6Mys^TeHB_KAr&inpv66@@yo9m!M9cJ4}{3~`c;xF)oBeD3uWWTdm$iz2eaZ)Bh@h89YzWLh> z6L3#FGwp&Sp^1!m!ae|Ko9ne!pw>W|hxu!rfhQ9Gk^OqTe;4aL2kE`_J`dz=w&^=> z&Tr^JIW4=vfnKZXt^H=SDD)||g6&kaiqts!J8$})`**XO=y&UdIX!*l|7sdaroB;C z7nutL3})vZ^p^jt5A=MsHxG$F@5t`ytA9Gli2U~Hwd|%`Cmq{zB73T6XM`}!^tv!P zbd!-OBbK|rpCqURBWNU0kcgIa_TR6U{QWUMg@NCngwKG(rYD_=!XB~i0m6oi{=x>(fgP=5?qY_& zJ{R6Aii2?qPo&sTHsW{zFf#hY_~V@GA7m%=4Ar&(Ppoo|@Zd3SYc%kH+z>V6$rw;0H_?DE6_q{t-jC=^Z6{0+eBLzZQx-^=d$r&AK$=6r(E!dglNVJ))6<=xb= z5c2h~+)VuP`w*!!)4CsVK732g*E{Cjkdx*iv43+s9kE%KD%Qi`kS9(PzdzYwbTg_H zA-iRkdMEbydBPjQF5|dkj|&6AYck20XAPei1Hb1xxs-VV*C{LEJ&aP}N?{r>xAs6* zpNWCoD{N2G+L34NJVDvXt&fFdg8n_QaRN%tlre~v5(Q~)w>R$ECq~J!*}@NK;X$A! znPjZi2DPVq3Oi{(a9<7BZ3N+%U=gUtDQ@j{fw4vb!<3E_gX-EoNX)0VPpyTNYuFK= zeDl7vz~i)LMnTre_0??WEj1e;*38&fGx~S+A8PjV)qQEqQChQ;D0#b!Qyv8E+u(aT z;w{-$vDe+*Y=&W`*c7zYk(g5ndtq#5cTlSvR~BT zJeGF+`^U&*@PE%m>aotwcNam%wZN{{ySzhiN|<9eW?_Y77DB7lfU>nYe|IvTV9x1` zgD;@h?6f8Sv{QP&7xc3tlu2@V<)YQXUG|CSqi?-CFK|MVY3i_(=h$E->F=|@^}csu zM8?QW15P5`sO6^q?oY4D>$u$W^$8gUAp!KmpPF*5)X7#{@V5Cw8IaAuA0iZc>DOM5sQlE%%b{o>9)JLlrQs8g3kB5BXSV+%$X_>0Ez|WMU zd)XP1b<*2^{tX?_ys9d^=IA=&2~d{wNs>e2 zTOBP{l3taj@&~bBs5(#0R^ap=isV-+1yH`ik~l1MVAPSEk2W(|n|#k!O0v zbh{Nd+@Z^Ank&f-g`6NbH@Gf1*J2E^lW0lKfOJ}iJn=1PQ?W+rNcKZ}GzWCK@pU9J zGzUIuv4%SwYP?N7DbY7Va!xs$y}xwRe9hj!b${!OMP0sk`g!9B)X5zM-7Ofkq>nT+ zigs$?2c+9u)BP7ybnd-%+FY0S&JKNUQEqgO%WLe2hLo(`A*D4p; zdV#!Le+iskZiI~)ikg{Fv*%+ScuK+3bD++M3*4K|3|-OmA-IQS;6PIv=~w0W>Vl5d zKKj)~)CX)b>u)&#;_v-qTFy>dW)1~0GnbCS(Kx-HSC(_*mU8gm&r){ zt3umGzLJ&gj$-7tofq#^(J^++)L)dT{*w9fEhlwq1K_8|n=U*_du8O}tf)xZEB?1= zuk^N=_G5gmzZDhcamW1iUvK{VK4vH^5^|o-MGWBNr*lf#O+V23_4ZuDuHD$#<+e4( zY)5drc`)XV*tc3+q~NO?(6s47x>)nO#G22%ZOz|u)?YFNMWSyuU6{J)lZ)i#@fW2p z)7oWZ3b(ZBamOT37qL~@QupS1`X*~bFH0i@_pX1~zx5vOK(7kYT&cU;_e(RaEA9XM zc0+9>_MIQ?hn<@)M2o#K{J-rDsZ#=JcYmcI%C6~rq?95x=ac54Zjwsn*)%ORSCaF7 zGcA8n?M5fvrL1-V@tvvHR{Cpt`zy8ZVk$=sQe2smMv$xNinp?f|Au|98!~Zk{ zkPrOt_k8iz{d;#$y4l?fz5`d|S)SaF>+l(#?80wq>(+>8DK5IQsV~DH>WX%j37w|w z_RPBvU9Os@10p+MeTBfo^UOQo`iQH4lQNoWK)FsyThipjymv$iEPs4p-Nd}Nj0XE% zro_B(6El{XHVb+`MUc~xSpj9ufp_b!QB*weP5RSX zM)0&-BqQi^^5(bvi?G9!V^z2F0!jB@NmL`z4mF7%XpU}KaGX264 z=S$F03xUVs)j8Dw=*m^ zBbP~d&O?a)#9@y@y3v^3(!6AKO6ZBC44in?>W%Y#jOHGE?H*quEKf)$*G?c&BFyr7 z2514Xg-JL~il>g~ENTmIFU=YMyWQW`cdquf^$cyR!Qa;K?*TLHY0tlG^TKH>Xq%3o z41p*4(@TRhLVA3Jc6$HTd1HV4+Seb45HXI?mpT=Ag*8X=LfyMW48B)t{@LTkasGn4e`bk(_#)AT_7%0ff zj{5W^>ChPFT~(HlSjL^V60xI1U$0tb-Xgh`nXH9o6{w&E$-X<1LfXl_UdQm^TnVIt z1qs6yHkCzXc_W;wg4aLG?7T`JTt-3P7qW`89tLkYFJiR7HzDHbbY>Kl&-`en^85

nz=A_}+7>oT;6YnmTRzdbJ=c>yVagfXt#JE>rzo-LVNdp@Cu33h& zV2b+-Ghd2$2qU$&Ek>qwWYNBkH{1q=!AQS;4wiz41!giwzr2{HG?^h08C++)4846! z(pLD^+tpFnI!mzxmiiyKmd6h0_(}ibLOEUk|cVbodoLE!be_auP zxj;{>cjZw}pUf!Q_lgAB@mc7LM<$=x#V1U^d|&PF&Kv)p>g25RA56ku75HmxEghqo zMYQh??pKPWRkV!byUG?R;!;{W3(>1Mc_`&4eVWan2db_*rKdaTFnB+43}6#W+_qxO zqU<#o11f=J+{uNXdLGBF{Y^1fjpzWIWzILk)AE2-iB?$}n`!(I>_SN#>|T^|-ojUs z7-hBUp-58=xDQR!d!9!)K9RJlij%~6%BFDW7osU02DeG)+gM;TI7Q;`$Af**ISl-Z z(D`%P-UtN3X^gQ_{`d&KG{7>wT~W(#YD^3Hp0C2(oRX9<#Bp!LAc0EIlHxnygP{hV zqInmiI+}LSeX^KeTLT*!+5(C$%5J$ggvyrb+}>Rn3jh8m&uPbLw;MRt2S6a32bCtAB5|g?t)Fdy*myF41c-t^7Z({{@DTo> zdtPyvuEs@Fk77oWxQ5oy!hJ3!o8uzHVtmd;c$#9>m6;xK5msJF^r{?nr7{PzxL=)1 z$vp1j`AXy3l!L7o3PLWuoxjx6J?dbqw9r52$F1~_=9FUmZHb{Zt)CHm(rV*U{9E82 zRm@cd=Ox86?t-GD(EBT+GB4NYzrMU(4-RlfxKPl^M&6@MLA^G2GFTA|R>b{$M%XOf z+nq!|F8NVJPF`plByh)$Y6szrlG650(Hvo5O@L)kjlzOfFxf3jJJdU{ZmpSg$3||6%n@u1X{mX;a*?DX6oaXbKBv+M0O&eDn-Z&=PV&PBnsYp^_+F1F{RCF zZqp4C<}+j@Vjqa){Z(Hy8pz)8-ksF)WX5BX}5gt!XfXN(&J zY2%{LST(rgwM&6( zmxU`f!0wgEEZHrgsR5RV8l@#wC=n{tVE+eA)FekV_`{Qk-pIQbUqv}dMbIKjtLXVS zR^Z%Y(Hh46W+4O1!dMXV4Hx_ zn=%FxToSdKddchaZNGHYV}e{4P{~;uz0Y@X*1#(3uGAJL6(x8o#djqV()VuVP4CWJ zl_MBhIMaOH_D(L6Ynp|~hRnpbvDPb%(qsAUFV)WWC6E%M4UtttTnY(A3Z6guC+8N= z;}S|qC`D@&0?KZrYU5T=TKVFcMzoMpj4I<27sJ~wJ9p>=xp4YyKo!A0lu^V*f${`W zDoyPZ3xt4*{zBk-P~zcqF0U&B_D-f4$seaF{^u*llE8&rD?Y7NdAcXx?UG8dXH2>j zMCpkd-U4}012X)iBVE9`6lKb*LNHe&a{M%v=E`rMwL@jybfI2Ftp?5SzjB5~ewm+F zwur`L$pcOPv`{AQA6#`(Ov1isO4S!64ezvb7XSXGh|9lxxQ6atXunGIhM@Yu^9bQ% z%WV$`S>Ovu9QC?Dd4g{5C;Oy5rByAGS+@xA2(URsm<35+((wNFegf@@&sJjRYCwxd zvy}T7{8ZgW`qiM-Mz4JqbO@TA2c7eUhw^Adfz!?pTq+4OdcNthlX?=^6n>q545rMi?E0)FBV$m^t1SE z;n>4XL?@VjH5gkCEj?`r_6*_iZXopvHD#v`buyI%!ZJ7b_3W1O&n?BusWIl-|D_%1 zV>THPo#*4wbeCLyS!=|<{^tR(4BiG_CG+3P{Q=~s+z$$-QM;4?#>u3aMhA1 z_-q%T1BB&%e*4Or(|KpZH(fBQVll#TtLS_fggC_Xy;p1ME*ezb-sSrm;Wg>Bu%u^? zA6TP4qpm>jrGpbomv2P>O&q6{R|w#@wsuNufTL3?T~_6LE~Rv3n7Sedr*V0OqEmWB z-l?p7uT%cs-KOl8dCJU|e=g5%xnHhBKJ<#>$&U02VEuK;fP%H^otw^Y_=>!fO zS)om8wJw5hZvBp|)wVg4L_giIF~|B}g|U5w?p238cQBzlv>#9@5!=DEs@ER!^k?Mj z;7?AkJF(bJj6Zq0$6eOF?NYOkx=t@;#?c=6aUhR#!H!V+yhEPWQusodW_B9orW)LH zSLr<6$u!;s<;lvle@da(_u4eq=@-5aodM0Sd;|0*()b+ph6L>C?*k_vTfz*3hk(si zLDBSZ>zaBx;lc-0>haEtSg61{8;nBExXzo%tP3 z5R`6`Vb$Rq^61GSzx}ZtvQ0_DVV|&){$)Xx{l$k`4WUxe*v5SUUR>`J?U z+3EJKtEXd~fw9i)8|&ZBQi_reijpBxl#JU_lpoJB;*Rvu8G0Jq4W6BHiF7X7R+4y1 zKlfwTCDC$=RV$v%%6e%lxrv&}E3IMQ=qM%a_KvLgpH#eONF-XQdDodJa8ZWVv)-E`b^i8+5glAt@>%JopL}B) zruc%FbaT@$J@Y=@GyT7={P@@z$`y8d5AF360C#@Ry+=OOLly`z_sEU<%5&h(UM9$b^$WdB#fUT;(kZ4l+V{LQ%CW98tS?2KsHuQRtVZQjftZs{!7hAPXqh z<*KdBq)>Q*IOG{DOTkPGs$|!b5nF93*efL%wI8l_d-v_pRq4lrPcn9UC+*{{Y*Y&D zE5JK;{2kVMRJJpuL(&$Kiaty_1RWfWA;c)E(5kt6sfRI0o=XBNPGU#uUpL?QsLRM| zEuo-}YnXy7I0x8skh}^`$MaVqi`&@+)(`w1o=& z%8tUz5IlR8#Dn_`WPY%bwL#WxCeFRILtanqMgpua5_)QY{;Y(zK8RhnDote%v<6jC zpL+cIz_K9Aey2ar9%mrY+AZV59g z$_975(Rvs9e~h_aP;RV%hPxodho+f7CtY$h3H50%{9In%FCyaPFdR<#t`v6@bY*MUsHpBR=)v$p5E2??bm5! z7A~PY{fw`{)2o?Mqx={!%F&QGz(Y7B&~8SORksr@faHjwy7gd}iq#4&N6Cjj)uKaIBSh;L@eLaYba0F`i-H{l8Oj-bgW`KnYQ8>pHw=4}GJ(SW0! zfcU+1$D(`NlLbJrS4D_BsMJbVFX)HL;N}V_&(B+zMg&zd1(|3Npc{##RN`Pqmv`%@nhM(gft3~~&YK>+qCY$!X&Yc8gm0}ay#B3koC<4r zt{9WNgtN{_+k)BHD}6!Kx9Dm}28i2JL}wkHBRZVPL$l!d$c$6s<-OowUJ#nZGbooV zEqg#X?){>h6BL}ZlXI^&s>SozAJ1ZsIG8DN9nHP7n-z1j$gSzg-8*9R^mgNjr9y@) z*BM(lV}3nkj9wDG*CkVa;UO|g^Qpy^#zJW$7rWPa$H+L?O?-g<9%8-&(UPQ9_wLr9 zU%8~rI=S@-JZi(Dq>0*1si~g5iRe^CD!{lopO**3w>P*Joni z)mRQY*-06udM7(2!(?@m_|x{=m3YkAOPg6=FKv$Lqs@n%(#llm)aCGw-rB9$kP2i6 zJvU3-E}WaEwV$XBs9G4F<{Lt&BmlJEHec|UCvi7+_m+2^*1MY730cs1?$|?X)$M&_ z&wPOyp|&r^TH%^Dy8;na@vxDzgJuj)io0xQhN&vC^OO#bl&ojgvY0pTUg`3#IRM)r zoSIao2f`o9^UE?{z5Lb=%H8I-AK205wH%dG|JGEZwC@+_d&D zc659HwpV6VZsaVL&75_A$C@i2yA)EoGU%%K3bT;|m7(*ozoq*uyqJO))>C<=`wjS} z-3c!E#e&VoY3+8nL4oDsm@n-WL z1u*5!%cK>%NU+<}-R0H6)?iK{8Nr=YRPG`XTU)$Q7Zg<_T3Q*BlLBePEJ#1Pyen-+ zc&EOT=-=;Ju}`-Jy8`Q#|rKuTO?*qdCsqg1-wDoU4m zX(u1GrBnLwI@6!PUHYZV-QFvER931H1YiAfRAiBn^4I^!x>cvx<^6U)JLLh>y0h$r z2TZ%qa@ABe(B)0o-~0AQc$;!(AE`dM&D*v6|Lz$peZJoS>IN1X(6^00+oA-zVhwFW z3LXhZ92ZG|ps4((M=$O{^A~S7-s6kWM0ZHrm=1C^wM8wVR7ZYNv0+QN#{fTNNks+~ z_y{fu+Go%Jrhu8IKnziOYJLi58g4K%n#6V35s6|Q_Fzc<8X*&*9up-Ng>`v^0g|mD znxg}IdCnJnUET-xa}@*MkBfq>CeE>QI|d>IavW@b9t!XFezoVDwAsfgpZkgV4(zOo z0$O_#gxxu-Rp1ug4pIK>y#)>h!%L^cJYHK!!q_VazJmVx}$RJ@_`^p`UBg*jnS&wBr z-lGw^0$-8-c|74P<#Z!r{!6$IJ73afIdGT(dq~W}GxExL(0!d=#;;fAEOezx)R3ff zc_(}taH()1ttX8xHF)TjOHVFirdWQHkkz>6gXWTiY3bhN?#1 zW~Nl_qpMjB-67D>72V!1_R#VdgLhGiJF?7jmq0lIq!6t2QS}1#psIz%VCy~wqVGl} zwLw40C3%}EB{+AMo;JAhE-xoa5h=QW0Z$sXmDY6yq8aHdUEZC*lF)PZt$eeeqrQIL z-v1R(Ud5G&*v)oa_kF>WH5=hS!^#r(2A0r0(dc*(NTIPqX|1t0?xb>`XU{y1v3q3J zQyEY9josg_f#2e3E=46yhmuU#{;ePq_vCA2I6NxXV8#xoGd{mP9sE(oJ`!Eoj5nnI zH|X4wyH=9J-f=E6VtV^Tnty~pe-iSK+DG#x3-f`=Gzins)*x8vKprq;Q0}lZ8K}*R zvobO=`f8JY?M|e{%(^q<&c3v1*V2&o)1zq_X?uV`^WT`r2fq{UvyE#^k;<_S!_GB^xJZOzcbZ zT^*0K##!St#`mRNygC+X*|WxGjO|N1gD5{k(6 z2KosOFU=dz8u$wczzan zp1|{FJpYP3v+%qI&*Shs3D3{txeQkbIGiposdpo04)AWU1bNA{QlNTYzb(i{aOlqq z)F)k{TQ9-Mo=KUkh+Az7O(+*R%8SRTU9Zbto)%=^bU~-$>k@M!G6&s)xQG!gYWh>_ zoyF`nil_Nx?tn~UfoHWc9cGx%7bxOUy)#+s7GonUoWHp2Tej(fRK*I9v;|8JwS_PY zY->`_YZ8t)-QHh2{p-t@zxfbPUdPq=nO`4Pj{Cz0d+|%x(M$D^hkc8Df5bJtzxP9= zJ9=8RTH$^sm17z@o&A>Lno4vm;=m`_prse%TuLjB54KnDoMnB%z-?J_VPst6f z{}ho#Lp$W1k`8&>&=!eAnoC4IBV$?Y{);3mOp6`n3*;Io;y@UyAC;s~rM9RP^t~`> zK@IM<9^}t}f>Rf^ET=o{+gVYOPhR}{azEzg$OU%!V)v^Ys8n)7?k6H@2#2oLEoQpM zTsBh~n!&xv4Ajl&gq&lH;fE|BSayjRoBp2spoU$e9ni^xQlb$e($md1INeZ;l-MfZl@dg}lK;ykX7S!yAb$OQGyPV>F25Y_H8aJ_ zJZgWSiGkk9sf`t|TgmB&-`o9;C!e{eMb0Gvtwi6MNImID5=6Ap$Bt7Mo>)%H*mU7> zCGCO7`s6iFDtqxt!<0{CK6cAYGq|_+;FV5YxUZ*#IbsRdWym*{aMFoBkTXF0Y;|#R ziCfk^+W86aKv5!+D0R8_B3b_Di>sE?KF`X`xaDih9JBh6L=yL3ZS+l+wnjt}O>e)q z_OSOo-}N4$z9Xr$ax`#6KRHibNDxOi>EDj-G$-wY{B~XKCt{@Dk#?NjR6>hN73S_% z?XU-msoU%i3kqtr4n&#UHx4)^z5UdM{s>7uRPA`wrt zd}Rr&et{?2JQLpCXLhJWJdtGuychT3i55oO4o$@Op^4NMHPA#n&_q1YL{&X#qVp?x z>zqC`5!Ds>(L_gYgC<%lqKOp6I6*A|CFpJow4!K@!PtLK59yOFcMW|9hH~zX3@UFCvL1LY_y@XipT$Z$c8C z?nM%bBSvK`fxG$2IXKTiE)+r0L>PS$O|)PI&_v&@NxN)E@51vsMHGEjKoLdL+f}v1 z{lo!^CgLHvQv*!|lm=!2Py#>{DXdb9s+z>eDk+*sTK$fTkzdCXxr_cYJdr$*&Y;uu z>pNkqh|(V)AuB~an<%D8SqoVdd|u2?3pozY3nH#ae-o|)43 zltL#h#ir287fLJZTq=g50^Tq#6>&sd;e4IS#mF87lISPTF#ZupMmNANmXOjEoX?UE zwiXqHc!pCh3mBqf^o;AivO-!(;uyEG2!CO~Rj?!C{OBR32$(DpJ+!OvX7tdYn~_7$ zBm&7Jbv-D3tp_>8dO{WTp7lW~trsBymUz~4VKp*~)GDoL49jjgvy9g3ZDVE1ep`Rx z^uURsbPW|4DN5)aq>$)$T)YfEY46_y&UheXLVqy@BA$|lA6_E|T4*`YLg7FQp4`4&{j0AQ~5>7ahd9@9(1Jvy%~5PeccuC~g$Jq*(=85*hh}Lnb1F z)|lZp$Wje7&NiUWBB3KuQ9n~Pd;pH z;3-FL6>IE108KrAg35ECFBmhhyzz<6X(?@Yn(?j*9=(E#@C_~gg^+{Rf!tnVf22p((XjfqII2;zd!`A>GM7@^DDuC4mI_R7?;sSaXKGhbP z_Ik8IM}5!iJmmY(z_fi(pn&iDF(ne{oDnZsDTlmRfzh`Tr6obFvOLs-4w?*a`QeB* zNMk(B1tN9=v$W06?37wR!@nefJE^P+ z-zuv-=S_E!sIW3Rqx%(O#p+3-!5v(zpQJ4_K#I}(%_HYRWryr@1y$uSZ}C;$`u?sW zVUY>gWA}+?vs*%D%z%DiwK4ekQxp|*gJ$4XIkUk%a#b6ULaNFD%Q5eQs{z(toDc_` zP~dTwwg)9NgbWc;LPIz=16vA%J4i$cselrC4=5o?(=J$eF%!$e{1~AZYv=jO)f6N2 zT|hH@H{qQa~Z{H4yXO~1Vsk{tJ#MR!m}S8)LaatHpM$7 zWdhGaaYC1%O}Y^sBrTz5J6Q#&%eY?Z2m~{9&41dVhVFQ)l0H|xzwQigmEVL7+JW`a z%Nr!cjNUh2)K5`#5Pt(Y=&XniLi^PsI!N7%4tj*zwutDUfrWH$@AlgFQ6KGoUZZM} z0x=QzbD`k)Aet#IT!j7Lh94b zzXNN-j9%D-5R!nhT;~_2Uq0N25!zB1U=8z3?c)zX(PUK1O?dvX4XaQz$M- zCO-9|f=n(MMFq7hfX;Olil`v&UyYhdiV9K|!XIHAach7II(5Og94H>~M3-{gGadz->sy`AZ53A?LIn>ndl`q?AD`ehMfrn*8K3qpiSR~g2TEKlJz?&Ht6rSV1wQa z3!)fpWnd-62FXNhkn9F*(4R$Q(48*X4alH7fd%s8gv7UdkU^Y?3|a=eKWy7(@&7n~ z&Dc%PVGa4*708@$8F7(SETMa})&{DQoZp`EK3^#ZdgZ7eBan2m55EG8faWmpE4+wb zfozsyT7X~SDSn0U)rwd@c17;Tt{^hSGh={WnLyDidPD($XUA2afgXS68OT%^bcj)) zwUC5C6swYU9MtGj7aRC4q9Q!*`t^kf$dS^Z(YiQLiup9a6)2^@KK5g9G!LgyAOb6EGPoXTND=((}DfGpZ9a_Ql>x*}Qo=P{Qx}=C2r;YvyWg>n`A?&R; z%b*q0@8nCAO-GMRna0L7{#+pN6?Ctb+hhVTEM(BAPqE7l?I3PLi;PG+ z7>}+*>LBhFpKgOKCNn{=ZJ5~S(p7Z+IZFD_|D5^krEv#ts+rxnn zUsT5fMYW|5MHPs+etr~{5-2K49m|!cE|kNwI7LxCiPa(9EBgbct7?0Il?B}qSKu~^ zyCm)piz$+(a^(qlmZ7+sn^9fUnkc`mfexL>L9tXD@+h~T-~Pf5s_CTopPzs#)hNpDv3Prz1b>a|u{>Q5+rkPvE(5FGX_*!xo3 zCf42Ili};SD)F1Cx-yE>3E#;Kr6`^1y(h6V0H0&+*MrZYynVNKRXyk!@JQxfEE04n ze)&>jEl<8hyu33-Ecq7KK(z0H6$BC~ z(122SKMjIjOtJvz9sMK*QLe+4!?(R`l9vLzqs%h}lxj)>%loZYR-PZo1G`@%a4ifQ zk~-c#4+#EZpmyc~y~9q^R0(OAk&-WMl)I+Acg#lCt!PoO6txpnrY$>eGlCxsV3LJE z>rN9;=M|yrS@(J$)(t$7D6M}YN__DM>Q)Wkf#0Ml?EzLGeBuJilH(75)kDLQdQ^xHu%0vwh_Wb6q69aE|n(RPmkwO67wOzvdTEc5#}P2P@sCg0;)$2Otf4=ElT9T$x(i{3bRPzqCFG= zYYMq-8KNvnt!j95o-fFTNvTX=>|%F*s?I`J!)PI}3iE%xE|s?e#Q{{sJXlfq@hcQX zAnEC^!<}8;#Wq>xPu{l>V+^Px14RTuyAF&<@bQbzpwB`aPRc}f-azy+Wfd6 z9=IU-_Wy(mnjoTrq{3G^pqCp~8x=jMASwsx#RW~S+mD{06or}gRcN)~I=UCUBy4<$ zRak>v$ly*d;KB7U3aM2;@s9F^=uf_sVx8ocd#Mb1+^>V!M*WyO)?IQQ7RCy135cJH zwV`m)uMqdp0^X`cPlf^+sH(fe>hC{#o`da5fx;t`jTYvDYK&>1WvMD^obt*9!3Z=7 z57S}9ievnVG@5q^R%ZXSpog*X~P$8|XE^L;iGH``kjm>K2@lnU$39O$U{_om9&hn?r*Uqjvg* z=pK5`xP!YC9yzPC4((uDLonBAo`b*$-D9e7vQzIdy+Y|ba3=ddWhW#6IdgGO4R-E0 zJRRBd!ENw1fge!*CBMCEhZK0rZV_>_5V^OAh#OFH)V}Bj#7zniH`V+6y9>tun!h$N zJ+*N*(=|`!bRT!D^k66C=INwXzKqUEZK4#2&-I04!L!LF9A@D`%q@yiifLB3BskN4 zW(%vS$Nn+R8%TYZj-h((Q$7v6v}!m%&GUL2ubn(6)A;GI#yz&H%ex4;n_ciiuo|{6 zBq+ebLGGXv!ngkBebfc{E6(!SIGOiI74%)+A8oRYlnx8a0SYJ(>mns$UIdBOiXQa+C?F>3btC+635aD06wvlPY7uX9>cWxbe!R_L z5P-v8%3~-s*LmoXJ zym-5zU+O~#FrNv~uvnV>?hA+m=0se}!?MLQD(HnzfYrhgA;}=AI$ZgPlWB?v6)eGKTgbEWF;3t3!}>moYkHNMD-b zY829TB}ZmN^`&)p>XDW`YjB3XFYOY1)b;X}Gu{*Rmh=d1UiU6fCcMLwXD_g1z(vHk zDMY-Te3pD#fS5Ob0e)gRFdew3aP93mDhYt)B(Jwb?OyiTv!_JG|cRQ%;r6E7|EuIA9dUUg2cM^_!^G5313tIQ@q%#V4 zzG4~zpE{g@0dk6z6L+GI`uduMcZirrmQ}Q~7oWlaHAlt@Y`EtC`tf`_yr@j#UWzsR5kl>XgY_f8f?Qw)goV7}ZBvM54I&VUwsm-ZO^odWTg`&u2`uy)%y^u*>6@L=8p;oHQw!|d=eBB6R%#c?uXs$-h3f6{zj z^CKcrCXI)`0gF-Dn4Z>nTm}6KqkJIz!94$arybHw_1JMs%@WAaa<`GI-sbQ+lieE0Gmfl`yu6o8UoE=F zr`ODdJaa9)K~TPQ6Z($gb&N>6YF_Nl$;fugRPrbi!>)bYIZ3RatdiC(-53>VMm-x+ z9W(tSx6?ziD{Ka1{$*WlQcp`THa#r~a)wwR$o=cn33&|q=vo3S24k4D(=WGuknyw% zksE?x_m0^V!&uHWPZSWf8#2#J9}w#|IwnDLQlAA`d*aKc6VzrcX>P*3cD~9;eP8t0 z9cRIp8i5yy6X3vJu4Cf^9Cu{Bl;_VMnPf!E)}l28tzlFZ=+pf6*|lW&1jmi@gI(L+ zOxKQd6HlJT`k8|3i48m%dXgp2RP$u775FY(`|}0~?D)m*B`7UOrHNuKN1JJV4>+ou zN&NKo$7-+t?NMhx9}AxhwbWPU#L%2KnwgDB!f)P4Lm-VXUE*%*I{{_E%6a=t-tiYSv4^KI)}l<8Gp0 z_%%K+3GxW&K;xG>=-K}tl!AqTf`urfRF)WlkEZAS%F#-TJlc{$Mrv*E8DBEN2he8X z9#K$|l|*&A>bmPQW#=7D6MO@c9_B~PrE3wPt1f>-L3|z72WF z6eE18E%9mL)Pivxf>)!_8f9rpuB!AkC%>u2SmpR!q+Y)`=4LFpiF%ze)6!_9CrZ7v z1(bT33uKUjc8`);^9h9DN~^#Ne$mZ zdvpZ#e0dP3$i_6-ay4LYi6oJHX$riCz9Gak$ty?s258cGgJ-8%QF)JVXwUeVTeq6+ zX)n7JL~#_pAEb5EOG1xD7IAL`YLf|k82iy%;y0GTTZ2k?uV>^=VdTEIvy}@X(Bg3n z-5DaO7a_WfZZvWZX4E!}UTWySX#Dqa+l>1iKIm{B1YH|*9DGp)Pp%$A9Le>FTZp^g z>UD5!l+#a<*L=WO+eC`IA`5fk28#Toox6!5FA%*0>vEPhv!J%>+T~f#-9(Rfni)Di zQ(y~6_d7a1hekTXg-`N=X!=B{g&hYvnyP{44JBrNVD!pnHS~*h#(KMd|D^h!jpiKx zo>UPvgzicyMrJ~Ro1}b|`om2BJfrolcZ?L@4HZto+a;Cg91;+fN6^ErXnMQr1M!QP zDH_a_CE`p8j6ByoK&0GO+Ky=vIf2dawQ4p9PH$>Ajc^7F@mk12r#&Z9UJ0mojd6PW zGqu<0_a*xV?1c+!$;fp3Q5cBK3|I z*s3I)=KkK%OB=@LsVp35gEHzmb@=@(xUDGkY{wK7)@ZaRSmDbNgzT5Gt zKbvpQtG;~;t^ZGXRi>BH{~KO)1t@)v$g9c<Lsf(UNTW`4}J*D zEB-@{^@l%jthzpqRet={eYfXVPyB&jJtOj~xjn0ma;paS2H^WBXO>@UF#7v|@{P+J z%J^zKiLpemYd4BKDLfv-D!Gp_MaSg z-Nczb0RKZIVG(?uFLD^;vh31mc~n{kJeh|0y}`I1#B&lZ%1^Go4L_M*Tf95;|0*|`ATU)EK#?ByQ4W&M zV=K7DHtZ|Ul>Ctnq~4ZaoFMw2{-5Z;Mzr-mp##hRO}<;{z%1mWbij%2ZHe!W!AI{L&1Fd0sNeRm_&mV(*gIukQiV<}`9~P8jhQq((W>QJD+;4%q8dXq| z4Q`+^AGZJD4PA@iYoTN}usZ*TvNwT?s$T!c&zS{g1BO+0hZ$4^7u?FFavX=_f~lz$ zE_G2`(CX&Zx}jDKo0fIEFyjIr0 z5-5g@Bqwak1^W&wNB#n8;gXYmbxyL(hSSI$%wW(8zX`NL)?j$fs1hi>I5Rw%!I~z< zdd3ef#!-n<{A!Un=oE|n0oJx?O<0FD;jz|isiUt=ROuB?SfhYl??Id$TD?`K1Fmmj zX_IQr_SL$?g)=E@*7=lc}_Y zwtgkWNX{jSPqy_z-~wgvv8gR%x|V`8|LpFOWR&cVb(feP?e{HE0sImHw}X| zM^?aP0VM*h85{EZQ{p>ldCDQ*8OKfHfS(fj?)!7H9n5g2lih)p_AcahS#<}bMB`;U zfIIqMpu8t<&x&%fw^ySNWm{y9FJr%T=V4t~06*FLUy(E4{7uf>_Ad$ZDt=pV2R(R4 zwMn++9oJ88iO{2euVR4dRY>Us{^x8^HvQem7|Q z$?X+Yxie@4i1a;;MT3uy3rUBnOSCl#a;0Kd&a;zy0{{AHiyq(;5*fr zFY;|n@PvnvtSM+;hkl}`hap82TTY_?v6-p-&V2!WJpN_qcYXzaGOqZS=Ctq+>tvP|qYzdH!@z|KRXU-kkqs%w;>V|yUkMF^SEB4VXCyBP3wCCH ze*BB4raULS&paOLJoM9U+2Nn&hA*G;^pyKs6~T*IH7bg;6YqJfcno8NTo*PzOPTul z$#G|_jP|J39ByVC7bS)|Vd4L7b`o+MzS-2_e4!p#rnA)d;7?}5OOGyaUo{O9&pY^c zNg@-(ZA->zGp2UQ`G_-Y>&u!T*y_7IDTMC`*?6YE9QjtL%36_U%T_ zJH*J7pPo4(+{W1(XT5ard9$S2!Ig7k7pCUjScfh?fkm zCvPF-?rC^8+&7A&S&}Z4^dRu%shM(E)I1)`!eTS$m8m06y<&PFz82W9+6Ka{WO9@X z^UD#x6=#H*#AN*JBK*;H*KVv5XW=EJNKxP!1^-D!iis=K;I}Fm*+gKI5-?H*Rsh4T zcmM2h!w=m8%p=k-8;!g6-6wgY`9y2cvv0<~*$SKQttFvzO*>&Xg>5YY3f#gnI<#8` zG+a(-@fQA%!hnEbUdPCTPqccBw`su9=FPdXQB?+%!iyXOOdy*v^6Y3QGxDy6d63w( zc!GWfPH&{yJA{dE_~NQe#SWG?4sf!!!Bfthf10$g@FSbdq)r5nMMe0(4E`K@TMU1? z_n#&iM`3<-VTNs-1Ybcc+HXLwjB9jH#M4gSX*V@$QkS9S$CcC|7p6Y4u~#M}#%Hu?UIup7`9EKbe zpnYjId&hOx1MV^KgfjzqH1r1A=0T)T-?6%SCTdOoq(~0I@B_O3jIgi)(L2H|uZVC+ z%@NS4pf^$dN~-D6Vgyt{pCcplcx)EzZSFoDY=`F3=%7Zl4Q!ud9>Dgw-NjDmaBXu3 zTEXY}?M4vNv~%m-a#$aYa70u@njvWxa=6qx+r0>-q26csQ=NCf|7k`hS${+hnLgO_ z{K^eWyN-DCdiX~2PTkC?^Im|}BkaYkG9{alN%J86&IX|CFb|4;W^`GY1?))qRhc}l zflUo+jCHbOW#is4!I#yOG!s%YnZXm0UmE-dVjhf*;pgs$T^9n&$9(^^@=(_GS3=&TDauec(u` zO#wup0x5uJdCh8}`s)zyJ|8pkeykyjIU3#UxM~xPaPI|)eG>c?%|(dt8yMx7m!vTQ z5BHq|N4^DpsO$z7-q$B0jZ3lcv+f(?4*`2C-Nv{TF2=qaJBZ#)KE06Qz|ClgLk0hTJZLaV=;$9?-tC_;MD!^D^@4D_<<-S?E z6W#qwcf>n9UM!W*bGi3snW|By2vDUtkPsb@o$l2$>eG_SiSP>)*t5uLzq*E<=y5S4 zcV1xZdNX|UIK)<>8b$#l{CR3onAr3ZUK4Z!c+ad^}_jy?4_ z(OuiQIOo8OsD{V6H(NiFy~RoPlSic$JrOgte%fGto=6)+xip{*%H9W3x#u_czzpey zc(ne8-plUCxMkcfoIG}L5+Dmt_BLXdIoiz?iF-^8?hJX6&cF&hCB>=91C0|T=Yj{a z>9VdMKB|HCE9`q3>{s#+&`+RpvcEI#&%)QMu-hxajx+L_D;Qrd7>DIz)h(1|57*0P z$o(?+>mK+_tj}2po&v5ra3QBGi|O~&-u^$N_Kr?@|98~ht|{+Mc?Q(px?89{(z7{^ zy-%R_1jzuhfe!cOE}fiLuq zzUesrJy3%6nMYZ89&thj_2D%Y3tJ6R;1cIgy>jB|te>^nnL-$8Ucso(4?~)cZy(aP zH6&dZeWiouJ17N0Z<@0R`afl$(`Ma(|2JucDdQ|`xl9ad)GFO) z`u@~7?p|2*xfiQLu&@`7!igoyB6)RkLIdn(!7hWj&g4EluJ1efAe%;7HkL+CvK2JZ z&I&J^JNO9W0G?VA3=71*5vk7kS) za-+?!n}(mYnRG5n1$M4Se1|6{m(pPzKKz=WB{`>QJPn-iTp^tWNM}_qSvqFYuDLF` zB|8Eor*c!719hu!Use5g_b6_lP$Ma%>-2T2+Y5iNFQsyv z;UxQ1UwamI8n|^!WZV&x9Qsx5r_wm@`!YUE5(ZDGQBk!^=xxW@YwmC%{zVs1Wk%?` z7(=+7-7MdXsx+uOa!Mk%o~mSTn*$1D%p7G{{>6VEA}p7&^|kX)!W3(P)K;0B(`2Xc`Cg6hCyqjb;+bvYOby? zEOHv|bp_It;>$fqO`(RR9Z7<6?~-7A|5KL7rA7?#jTocOU6XalxpQVzilkzHt6B!@ zDcy|zo^>yqQqEt%K1WD?2L5_vLOsP={(Jqdxh}ZN{vZWQ+fSBFSV>h3MyVvnoSCu& zv|)?qg`eaOyw&8mOR}Tj4NB528n(ejh>ejprEvxek2sGSeJhs!Xl7#Is`> zjnL-L{G#Q}t2)i=MwFwMfwkHxS2Qf@q|y1GcXhK;HKqFU2S{~ktLEQQz0aSjbM%ZTon-r3(%=lAv5px!8CEzp;cFCkryH$$Bc)5(IqQm2<8Xg` z)fh@8(shOQvM9ssE1FO$Pm2G!otx?&_;0D5bJ18RX`#OtI7>^Q#U!IX;qu&pHjs?T z<(|Lg*BkCYpTIM?rj5HD`*1$yY3j!kCJ~nkSJl0+P4p44Z6_qm+qiN*#Cu%YcQste zLD?Rk=ZhZMz6z7()UsqL2VJr+WqTyxyu4)cx-@28Jo)3*arBq43sKyrgBm+yRqge8 zyge!*-co-&)m|3yY={?ycq$?z-5ant6ts`AhRs~! zmFOb!q(a_w@{rgR{0}{<-}xw)0oeu)OshmleUa}Gf7&M8>AV=jJvj4oXd16GOZUS| z_SGmQZ1Hl7vQu(T=X@o25D56p25xK=Yc1wkiNpqTLP<`?_ReQq;uI^TK$}M%j$)oY1RCvUQ?pc$)qiHTFk@a zA9S9Fm)W1(+?AH~loIKIfu0%~1#S{JF_2y%J;fVbTqBb<&M85Aj^_rMWBBxLX2da| z&E)6zLH8T6q(FunV9!NI9^ym`rmctSkbgGLVfXk;U_|~KVP|z};!{c66la7boLb1TVao8+0k-aYFc{v&jt${-8qC{4%eFV{pP$0RI_q6{*5ywkI@I}QV#yGEo+DCOE+T|W53hc>TZSq293WjH2FebOiRXItlPPRI3-*d z=6J@D!=^#bi{6*ZfW`ZJRAV+QXR}|D{5K7J=3q^ZSDHDn>*X67cwSD(gZC(H4F7rO z+a@)9%*OCKXzDe?mlU0HKIm+8A2w+P4ukmS-A<&H@HJ{@gI~f$i7RvCR=sWdRfs7? z%vKkDqcAqpZ}3+h!#~^kE9Uv1#j?UD_(kte@CN?V*aIDBLY_5;T;G~|DM!CQ0UmO{ z8c&?I#PT?6`W{e3LuKU+@R3a(TD{{nc-F?jRz|yJxwq`#kjuM=sjf_9wdB2x|E8IM&~aI-t+m_F|K zc$wU4htmM?&wR)oNnmx_%xG1#^gw>jVIi)~Se=gC&6UK|uO|hWN z;)tgrw}$f)HlEX!=WtQ=K44M8ZHvuewr06Z}k#8g}J_ zVf`qsa8cs%wyA}9ZmZjP@ux^Wmbv*~%1YVlnPgvzY`Kv)^?55ptpnV>a>FVQiEQ-G2Wh4&@mqNPHv=)HPnH!Ua}K(-NM&E z*TvXg&7OsJh_~$^n{c*)jmuWT&H`*ioRC~v$!w104|$6dmt&3bbwpL4xh#hjhOuMk z#mDeros=>=<|O`7$^#rWNDAcD=e@C+Br9X84eOV!Pgw~YT0y!MA6+}HQk8vljnOLc z*QgCHJF8UC6BAu_0)NBHrY8d%1J8fn#T3CF2-o_ACk zwPkhv$9OxH*TDuXqcp7f0ILL znd>cR!!F7&w(YQ-7iKLexY9+5UwUP_LHhVrhV}8m%+*&)VEgpyy`>N0@0OAV{QXO5 z1^yaJQ&wa`Qdd~Ie0?0kg_Y*!F=@wsMToxQD2)|ou_CGk_3-2z&Ew@s)AAE z+Tdfc2$#lfYzx*Fo1&aYu9p}TNN+(TqT*LxfG>7#U_jqb$r!`E zn4{;6{Od&nc)s^wOC)4tkPH;3?PUf@D?>Wo3m(s%xXj$Ud?n%R+@9UuAZ`_Obxy%D z{hrn!C86^s7So85HO%C6Db(uE3LHjydd;`7MQez(Eng|E1Xd4*B^iEAAyUf4+NqE` z?#YX^pY%?L1P~Zq!OAzRL0h2vHu8AeC&g0NeXvOnyDY^zLo94n;I-zeDA6;hW!fg~DJ2mWvCvnNPC`S^k-%<%T7s_9yybl-N!x?r*^Tj=X z5hR1r0!G=H6K0R)r*(!q238hv-SJ9WJp4vVVN+j!<;T?ut4beftuq}164}zGEF@%$ zk^jU3jTUpm26@82N)m;X=!QUTp1T<}$-b;{q9KRCITXfC zZV$AY;I97c5F886r(a{w>%bwwo~)V9O<<5T&}t7YADOkz%n$GqKJ5^K{s;Qz}zYv-=3InuCKNtbjU+Hx^8(-!;W zj%Y|DRAGTRCbx}=54YJlnjh)O@Nom`I@wD5&Er+?3iHBH#R~HBOfJQGDrY`=q`f=b zK{LYu`^pL%p{>9IT;H%PZX77A%1!~?Eue6GDXIYEJo@prZy2nV` z++(7lLrXD3i;*L!C`Agq)0N}IGAi7vEZ3zZ+hWTxF5nHSpgp=;Q5oS-Rj8ngy$7}z zq%^1Gq}LI=V zc@gQV!Ggc4}aeo2(R^rr*X)P zIN}QA)B}z6=DI*AFQ^>aX(?6G>ib(uq+Mn>-o{EJDh<#wozu~~hR#G0-O@K;Cur)t z1X_s-+8?bJSE3Hop4uxA>$LHFaKZJzRtM7mpkFBh@2dUpwD$N_x$c`WFCymrsz9iH ze-LwfznFWjN|cjYg5d$dH-YvGS}D$ucE_M3%usJ3tt1iHV*=?7^2d!^73@d?qGI{J z!2U9;+vizQM^Y?WE1tMPsTFwU@B5W-f=W3b1p44P;9ApiAItT5rqwa^<|pOMygb@> zXwE>R(O7&%!gj>ZxpHdtQb?Cn);R9tCRoe0M881$(Gcu|!dy1cETvhfDx`5t5;FJ^ z+j(<5)7<;0iQ0B@dq}m)42hfPOqJNb-mZVO1ZwlCzuz*@Z*_fdfAPOH;H_c3&+~9! zKcDUwp1v%tlaEAeK{M)~f>m6i4rnIbUpNlupMwuQZ=T;QA9<`^K4kvzbez<7;!RdF zm8P^xTwM=!6|}sbN1U4v_EM=nKWqcdWcTM2x60=^T+0smt~pTR75z%^c?&z_uBMCL zxkxn_k`Tr=3TIA|HR-+ZUQ`=cx8LbzMow;jWp7|bf2Ir8GHR(5BmJfLbJx%op}*SW zz(Fai3FOB4bE8>mZOOzrWtUgZUGAGr^Zegu;5+6+Z6Mxa|9hGbK98%GC`FM@?Dc#P zc^%P-^j@4bL?=#e|3avLe>!n~SDQPK;w*oPL;QX6YOOfW4`QB=ZW5p0v7}*S#n%Q_ zW?Gkhp5uMJH>zK4sP~F$6T$y(_Dt|jNlfE3{90dJ+2p>urT9ZrA3RlSSZ_ez8rB3G zb}jRHQtE~aYmlTXxJ4XQJ)OIn#dqG$tgIlGcr!F(2Bh9a78DUfK1MrH1 zH#c(O+ZC^=cPPsv8nt#AtT(R6TV|Gk&#~03MvQr01rrL}6cX?kUxK#vXBIW&25DRs z&XP@@r@P^m=s1)1g9{_&Sjp_5LC*s*(o+|h%@237EoqR5uBkZ;$_F0K>i+8AgJ`x9 zk0FygmBSk1FxL-x6^YUO@UQ*T&J>$ z)`_K^-!*3lZL*|ussHKz&g)HK_GHe^DUfP1(u=mn+TL#xXUz1@yPL(QshvMGjS%AA zg*H4^L+MSxQ(TRh;+RhA<-ga=5W)<@m(4W>;d!v|Wo->v9iWwkWHM=%{1&kX2O#7# zHCk9aiiVHX!~WjWbWUj&-vxIrZx(x0(z&2{h>&8Bm-3olBbKZ~_%%-`5s$gJpoSd+ zYHwR4#^d$6FTJsIdp!-XDI(nwyuA@VC$@8PEBqlgDz=5ahO@{jY58LG{6+7x$7x(h z@@|+Flg4us&B0cZTrR;VshAdQmsW-W)$sH&ZFY*CdL+7%XyyU@fo_$dh@-r2)Lrqc z>d`q84uuHxn#g>TcTUGSwbWW$?%&nX*V!`w>e`PZ{mxF-su&R}~EzF6q|8wX6Rk&oI?o*ko) z5zZ0sF8yNewwYypJei|?zNzmm3PBx+CzA+^QH&zN{%m4~c^V{yComp{0a2>E1Nc&5 zgpjqKlb1Cw==9iWETQ15`bMAjS~8VZTJzC&me^_W@Sk-yn8SXc07W(R%1p>8U&M7n z8g7RSCsKpIrpOTdEsBi5-xHDQtHF|~S3Wc7p{J>|8`__lnr02Tx>KQs*CWMT_>j-3Kjt33H{|MjN+8w} zfbN8}O&&b!53iWUX>e1Sp4(f&K5$atAUS`lE@U`(UbVzY^fY(lVv1I5;D{yIX zy>XYE;V@@r;#<7K9vu9&UMSg@8|nUG+mJ#a@gU=l0)~ocOopGhL8O1izzZvJB;wxiQ#;v6vn zyz)I)$S)(FY7) zhx1?B?kN6~o}<|@!Wt5VH3X@f2Jo9YBkf8@FlNH^GDo~hueIWou}*0(!yQD!3k&hB^wtduFj>?0Oei< zK4_#6?t1Tx7V+HMiy$JW!x_@9y&(e^g( zk>>t+uPEk8w*r<{bY+3|_~m9Qqs3B->sWp-0suQ$0#Vw>$oa%Go z6t@zmxae}wan_ew`sX#R_}grD2yz1@DfZx*-{rJCe`(?)STj3e6J42MY-jK-uUWV;*3Ahv@CylVmfBm(c;XB zN~;nh^m@s|`LN$;P-5j3+jdiNHPRBxdf;ZNqx^lzJxspfB#=`lDAQp}Q>Na`w0&91 z3`;vdtK+LF$8o_Tk>*KQRCpVD+o8QB@lRzPhYj)v^0%6oB#QHgX`5a8N|y23xDEDv z$rzL+ooTyRyeOabKc6cmszYskAYX_9?Nei0XDKXfW0(7~I2HV^io!s7O~s{sIpt{(ocF&-#-P{6byF5Eu=XK_G^3Ve$th4-6j-M-I>UH97cl0dI-0-sh~ zz15Bfl7CB}HTZNu}i+oAuB`}4T}x>v%C$Grsi zf88c$M&O>0`&szi)#ILq`|5Gf^W6=5JGg&_dj#%Vac>+eXYz1Aj5}%WOoJ6l;^&F` z^KkI=h-$J~ME?*TOSog|p+L*#2rVme^Cq{)@5hN$;D4Pqo&`TDVt*i9L0=C9-mDVd zB;l0pt4nf3gZFA_t1Vh=iuUhXkAtJC73=~MCFJw0tqV{@L zO@aE|1y1McT;hcM#f^6_jy@veUSo-2P^jwo;}C-%#>} z(S>%~UKNP(jSwRfF#>Ns5#B^21qo8v(1Mski+^bZxA8AhqWZd7LwF@24+0cdL3>Pf zfZ{4>A6`v7pdr=b2!FgY#m!>H^Lak24dgLE$Rh)}?xnH|6p%uw4{^+tLih=8rQN~F z)4}D^&mXR|!oF@HY~TI0z^s9VRifV14yC;ZvJ5(-ixhSg|3DYb&&lo8K>A#*p>jCE zi=vs9*7-$C68sCVTRmpaCC|3*VDPg-YZG1ww5-olQFqaM6n32hYrVK8T=c$4wx0d# zf8gEbKX_O22XUVo7ub&iF(0B(SQW+JpyMYIpL$*)^)=&6IQ(6h!diUg(&{(hJzWJ3 zg%&NBjgn;wsR!a+^rq5p&@_Q`W5?Zm){YbDjP+)XHSnDoM^wbkFzuik!utLGsULmN z*he40=W`$3bJ6=1;zabtp>liu-n>$Zh)33b3_eIEl7t~O4LBM-(S7TxZqjbM>mA(j zHVOLig?_nN{JEX>2KJGQUZQ-&k_X1j!Xg^mI*ggJmW$p6ec#7(mpmoCa`fgMHM{cP zNECPVbC$(ibbgd@8gg(ZShG{w%uRvslRM=5=jH#9DDH*EBD5qt6{|wAk7mKT;I-ZH z6{h2m{y|qEf0jSgpd#$JM(nu8Vw3UO<3$>vVkCkk_sJdK?*n4RZ`IxB`L-?>JO57D z-cSym-0@5`;>|+5S(Jl%b13kkb2@yhKE(xdOlAhtCwM~URD&?tCeR1 zYlG~pVEY{Vch|WOK(l1`qgi@AHT8jTE$4o7D=XzgMGo?zejMbxoS%Zr5;Uj)Jh``y zRr$|mr{PWS^krp4TzTY8t0xA7ZE{D$Ub4ajpDlU=R=96!7ay)}NyCcD9HU)q;hu@Y zX(p0i=ks~y)hJ&JoF0zi^zcOUfjN}VJMmeNW+vmf#yJNo8(OK!f}yv*NfOxtaR`_L=L z3wPy9#?lCw-0|n?{+ZmdtlI1Ti+{g00>=SuydfgTF_O>kjfTF7l?$^) z3jCi~;gmt=J@G^|xk&?0X5<;iH(G^Lw0?A)P1&3bZto?JsfW0|YQE@(zRc%IKlT9V zs{s9FE^P3oHvT)s7NFOX&fiL{4K5^VZAoEZ1WfKwR0sNYa)+ckFbXDj+^F)p17ChQ z*WNM{8r?LeD?}a8jxALRaA5wvSHrPG2KhNzA!lcR?hz@@>3tMXfWk84jX3XEy*4F( zP?%L)4&=}1UeD$FL0Cs4`J=Eh3Y{KK;*K}OB;TnujQ@#d!iW%@B_KVLaQcsb*9JP_vfvY0;O%zr+ z197`PJ0NdL#2WNaE$ududwa4E&!xSdciyKmepsVL&Ymi=fqB{Ua#t*PxaU0o>NVh7 zPfZG>X;dzj8TsuN24|2rEk8b{4O;&-yE#tAeJ!gZZet`rrFSZ{wXhDs zUvI+=dNaG%kSFI7WHDdUjyl{mduFzuM;k!C8i5Z@<1z_pxse_7C6Il-ajovGnL8g} z2z2Yzyoh`zeX5Jexc3hcyQdo(Jc|TmfXkW3HF&=1I_bVWI}iAFX(nT9@azTRE?yRY zW)#Uap4|EP+t;^0Lf_)^i}S2CM@++=tbs7VOuF19;($Fa!UYdet!jGt-U z=Wu>t(k?n9lQx-dr>~hOpjREwedB(^6e*y0cX5~!7v-U|ZO7YKj}(N;*?hROwG?-(09`lR>F*s=R$w$Z@# zI+lk4)$0^cz2rffP;#MVA=mA>vE`%pD9a?}AJv(s#Mk29AHX>VEQ~1-bZEDgOX$F%+AbjJsX+D+uX336iBeCn0?$6+e1@ zg>I(NDX~i(3-Y4#c6H0frYalU{bjNYun?LGm3?ZC0y0*qMrju%vfHz!wCM{KkjO6N zLUyPe#pw4`i+r=TQEktNJB$8XX1*s*)5?UZ5l;;bWwkNU{1jsOEVJT_Tw=nHp6VNC z1zBvfD-==y+frbE^1=i>@eiKox+VA}^Z)v5clXS$K1tSvK6G(dVF=ouBw0u)^BgCl zi>WO!57Y+Gzr*?#ow z{Z(x3qZ=9oba9Y?F0SDYLO1MIZ1D^~w)j2)TfC?bTl~O(z!p!+6OqMAcyJ3~i|-S# z#X$>+k21lJESA4E7IKu-%-0!s_Y+XXH!L|o6%Pigm~FFJ2vr=%-2C6dv@lh-po$|O z16Omx#g<)txMD@&B;blC{u{1XL=|f$5UThNpo%p^#~MOkB@`&3ieClImEcDe#|Wt6 z0XCAIO>Q6TM+EDh1r9h`3-s@CCWO$x%1A#Z7?@wJ8pz+4ke8}O?RX&o_o-%%Y?0hJFlLVIChvU zd}e9L)lU`7klm2F&AC#c2yUcu#O1C}oR-D#DWwBBDj~FGfDOLt%7kV6b3MF!(yiEF zc0%rH$P`JgnC`w68$6&|#0LN87~x`SEXKL=CN_9dZXuAt9|qsV2KThY%O_vIUNzK@ z4K8SBs`_Jte`!f@B;*;6%=cz!l}DDX%^p@X`%CFE!WD<@nxW^ll4Wb&$Xjbx z=IMEzWJUh+##CH%i`l)AOxZpteVUc?ipK_`Ro#B&+LJ$WZDtH+4g;i3|$>s|pn{5N2S zwYGhNR5MMGXr^)VxVUoS;lcI*|5VRjSX_v!EQICGy{dWKd~WDe@bIAX5MNIII*q&@ zyxwrFiey)U&84_wz`E-LfZ>I{S9O$UUskBGn zhA{j%q!KYiKzHrD@~iJ zGsw5CGiz;6{*Vk#EdxI&go^?;vxM%JHffEA84Twx~Qf9OfvF66w(+V zo-r`!ncz4+{ax5wt(Tr=M#`)#z!gUIK<2{nRC*hU@*gL;%ITqgl-H3{cWy?}QhQgq_Rbt`J9rA194nOh90M zQLLzhO#1rTwI6z$3_(Im9>khLl7i2Q(ITUn^b5fL2iaCM1ihvJPF?*>EpWN=ZNQFg z3$oG4Tf*<}dZCfZE0+I)^pMBw_hM9oZK$oFUkoeIK%opz2xOn zDdGQy6+Edq`h_Je0?K(Vjlt6c9uQE@zx1J;)_-(h& zvXr6_NX2w1c1~L!56nLFKFW)mXh zP`g7b-TVJ&C8kiKQkl|mYEkPPMi zPfMW1h6*i4?+71xk|aw4Mal~Afv^_dAFKT%95r?zNFegI1P$smf6;W&`_L8P?nUqT<^a8_&-=eptg)wVrB{Rc(W@$Fe`>W&pjL~# zSKT6dTedGyvwsR@h=Y`+t51#=Sx93QaO{Qu3~-2uBbExj{H0owg2}6% z7FOSa_CnAGUB{5BFx&1DQh-z?cUoWDZWM9?_8NI*^tJ3_;VsR3pC`8VqIYa6JB09! z`8eaPGc$%rth)C$iF{s`{|z~->jGu}s}L6$YoS;88YU$$0#^97nhGtEdGGnx8=Hk> zNgHc**k{wqCc>@}Rxt3?ht`pW>vp7krLRYNtBLs9EdNhm zDX`d?@U+MBhoEOu1+*@`--i;7tt0L@%fE%^^jh)xH9W7Wxf_Umt*sL>k1cg#j$14r zf~KNf^pn2!y5HBH%iMCc{NPGClU1n--)3zu6!S6jq*#=@gQJl3!dwl8)!5stbY zm}JU#h41!e7Jbh04L?7A`aYC;zMv=Y&E8-K?Rs{+&ue;3Xn}$z z&`0_pAge{`2RO+3B&-DpcdvX)gw+A0H1)_N@IGo`HC+9Se4Do1=UG-u7RFhX!VtG5 z0&<=`bwSWLr&UBt7@d?zYef0eh)bo5_FV$Dnx3@2oECaV0dO$E-Io{!=A&0`CNHa?8! zasKhKzn4b&-lq$8uhFtRTJB6D0Jk@oR{H3Kr}uONO!!%$$$5Q6%C*3!;9iD{ zc+}-w_3Ub3$lnBpd=D_>p#p|{yB|X?_hZOo1q^v6H=rMeJc!@uD*}RC22DDv78c_8 zjNX0V!i;trz|$M)bP$(Dz>UXlsO;19joh%!|9%QTqiD;_H@Fnc>o}`zrW*G|TfBhi z)?2^x%2vH2oXq3TF(Zw9Piag_Q8pt;aQ7}9V0X=ZVP;_;2X1>Gmi+tT5Y&Y@aPf9# zunP7akAOp_*?M|OoIP@D*jB=itG0%0)oz8HUI%&V)^M8%s~Aa8BDO*bG%Xf7Si#Dn ze6aFd@Kj*P<2h)VI+T?;^`NySVGdKfWtr(pw#0O$SSp~$rJ=x(Db?POW47?XU~Yu9RQ28%DgE# zWqCSY$4p5}<8E_B@jrOu8a1%38w!0@KTjZ)O-(dS;s0SFs}HaT1AYz5AGgFO!7fB@ zs3Q@Wt8X`;)mQZbm`D-(n9h{8X6ci#~_3^_&{8v4qr3=hu>^m!S zV^ODMV9oXZG?(0ftf&42;jD1A14nfj7vaIrLf7?UTwme35D83H3H-PLPesTwhF`HE zse?sCDo$6aA<}5*UHRAL+Sd`(>1 zo-|HHTEv5cVDljnwo=h2Q`xP(9wl_^3Oq$sME}#6o7TO)h1L+v1$GmMl|-@#D9#-4 zPxIs0!E4PgE`cS&q3a+ED3qMSNd7xyEs~Z-xjn-R4ZWxGQlQV7vqj^84^rUiCl`h|sAr=fa)T)?O9NyxAvvDk}!PoMp{XLFwR}w zjC6G9VdfEx*)^qa03WOzHo4=}{waBSPL`QDK{-@Ff`qcLc&i%nB+rj1+K)fu9V_`GF{5W3d{17-M> zo90{MAN15Fgv{}WT!4_zwurmNsA8=2Qk9^$5(bULG|M8`jlwDqzQq!OZ_(7pw}=Mc zf@!`dPd1v`fN6WMYGj9b)Ez^Xs65vv0D$1_S&!AG527-*^ED9xED zv89};ftG@$bzyC!c6bMp0<5?*2<;0ERW4GH6ofg#`9F2;X=RiV4htj&dz6utwCj8c zgaCFT$%(@;RuTCdg1z8*S6HQr^psMthO<#vy(YJRwLcE}Pa#%zu)!A2PwiGZLhRrc zDrtlp9JK31q7}v-RN8G>zK)OfM`Cv&|C15+u*#d7IW~B0C(d5Yehqe=)A2F(goK-W zPq`pB$SYKVSFM&rLvo;nC($zZ{m@?-cjK5?JCn1HaLBc#9)dA&3;DO2}Yt~QrEnrs&04a{BW4zc0Th+EiTP&=11ltmU4cFg-4Tr{s zEgRVI;rmkrY1sDB=W$uHbs53?J+0KhtD|JR+Wmj zRq2EXp97GKgjDWnRVZmb&`e;47PR+NMMEkQ1|Gotx(AT{zXas=r|z&mPAzd;pWKIX zX$#Ssmr7Iuw{>Oihv2rB;ms+b76VWRiBN}ybvNVo3?<}#u*r&AQ@y~sn+@Ln?9ZUpr&5P)tLm1m8Nw+?lB8MP z9XTtJgLep_wpY(mT|YV;_8QeU#`Yyga~Ia&A#>t~L2q-Flxc$>=4D~3B; z3x#g;^RShSdj;+a-1Bfh8v=b#+_&PcgMNkiIrwPOz}_S7&*OgTSqWpp{SDkBaA$B| zrIs^~cznKB)`Rv}$(e_6KZE->@b%2$-uQ@=(LO3=etK9c)Q)-$d}_g(?SJkyBmYK` zs$5$hjb6*I4UDG0fa|?N;3R(A5*S4p;MlJe_^#l>V+VS)ITRM|7#nOF2*~^EuvIdu zMm!Z^ru32*mZ5vZ^Af0gU=j5K0)H$J_|!AaJtKhJ*5Z^D*lR!$^gWB%{NZ~VJ)d_M z13hT1x#<0Q5K&L-fEN+hZ0vl4#Qkd>s5$Xn4Q2(|d=SnfjsV5Et#A(X4Ch=qx8_Bx zNzt}9TQ5I#^Nix___fN&R~FG)VC3h33UzRm&`8`qolZv4wisBa2`^V+WQR0^f*eG2 z+08OPgx?YUe&^u#t)-k!nzrhjG4A+XJu(r8IDmnArQ)|ptK57SO7*PBODW+Kho793Yoe99~r@VJHm8@T;(9Aw? zAV4?luBZL)(q^D02|Dpm`=UJ(l-h0X^}JQDbYLzWk!R2;6B;vyZnF~T-_7;! z&wv)YE`JF4F}4_6NLhp}v^g+ClWz2Srq=6L^?GL4(-@iD{%BPgX3g>znyp5By{jGw zkTRW~W=6P`R(+r6`MNzwQ-?Ie;d`3ViK$*{S^_?I*Odb%?ig1c=%2|QBcTmI@{yJMLLFLLC3s`e zws)G9mFExZP_vidLzU|OB6!X!teD}DCCKZF&&;iw-`~eHj8SKI#ujfC=5YpEo{Rwps0(;a2-2Jb(zQT137l-RM zT!V2%;gaEMgFxwfT>rxL0j~Bn66PT(Fid#ffaeYg_ELI&95$bEJ+)NIB;#s-40~p- zlzHVrzzY0zISsu^AocxJF8DSm=iquPdi8t_Bdmm}BgJ)aa{HwNKF<&!>fh=|N%%bH z>Ous*lET0aiP{{7S-Pt>#G%sz3ji;*;Z_zNDTzA~xmmkewK;k-*;82q%>ZhH&CvLK zAED`cge?vnyqB=|(0-#3D5?8}aMb1nLOHcUo0p)?OZ&CC&$A8hPkI*|d;&;u%Ppnb z1Wm?gZwXuI54+Z-Gdy$4m#6AjJ-neEj6w;I)v$(~kxJWx&L?NkJQV3B$am_(W5m((e&nSoL+(nsGuHh9895eOx1srh)Wzl+Uxc_5-XgXlIKq{eBm?wZsVr z|4M!KKFs?Um)r|(`mN{kd3Yo4P{7LHQny6ZZPqO{h(z6nI;SJ0hGx<-eC!x^OX;PE zG4+-hU9~wQ6P%L~LkYc5T6e@X2VRP5X%x&nHUZ!M(L5f1k2H_HFqbRh6zTD3=SbUY z?y-3LBW#b2JqW4*eHdap2k(|Ay~cw$*Wy}$YwkfB6D4&mo`z0sda1M5qj+x_ceZIB zr)g0Pd%m6B&kB}w^4;^0U&S%PPkrMF={2T5-+pZ$Q4=cLN_RZ>a3gAz}93kTGX}^7)S9-5a>9 zxY`y=nN_&w;yQ}wDqIz~_II#?{A2+41oShWfFuICkmU!ihd&p>u_-dYj>g{w9gS~1 z>$=!9BY)5$XlMk%o~WRqQDtFqhW^I$SQq%x_`cI}>9JU7Y#8#caHO>{z5WPi@@sA| zu+eiv7O7m;@tN6~-)9G@L@6*`$&f`M9q_Hvj4>dMk{f`dk`21`s3% zH}q+2Z1-zyfbR9))Yv%Cr9(}5SUdZ>pt12{pT-6ua5ev?tAW*I+`FyG0+% z0j-Uz?iNoq^aB!;;FBBIQ@BWOunhN~6L0Em6t6HG(H@2G6O;3@Y*a)7lWNsEW2anY zq`OSf=gUlMt}>GF(??nx3qS#;M%9R3^MVBpk?a)Y@ApdE=4Mk{-Sm6aG%M2gzFWLv z(ve_TPBrF5bD@o?@uRpmwfjwJ^}{$l_P@Kk^Yex$z~dQ{pBw3XFR#S(i)%bQBW>~J z9{Tn&E8A&mcFD30{d~>*=2_$QzCX5|Wje00j0X4d$Yc2-(h!P(4Yl!y&IlNfyXxbU zmgOepGN;DB5BUR9kWF82UTe-b|K^$JH6fk?S28a8M}9?^tEoZE%7^p9vYp~jMTZHSYHeo(bOX5b(8kv3S;In26`bsu@(QB7- zqF^Wd9$_YrIm-;6;JnOT;r3pYh2s37A+Hv*;T7)TEZJ3s%yU+DfcP&F{KnpSuwj(O z9h@c;e!m4jHVUfG*e|jqm{s3<7IeqVjP^?~@A1#qB$tkxC+Jzpu=joM$@LX+mP41h zPu;QuL=i;ri+fkzlI~ih`yJ_jjs4c$?77SLW}G;#@4%f&Q=XR#($)%-?34^o^SwF- zt*%=&ZP{LyY44OVrD^K3LHIJptIcE%WgL=WWo52!SQTp)!`<~Ld>P>)S@8hQ`eN}x zE>Yk9+r0meu`hv(vReN??=r&x0}P8Y4rs%S8jC4{l}qI?46h0mZr!|QIY8-)iJ^3h zo825-TFl#3P-D^Ds%tJRsohKsN-J%-cLudkG#8YSnU(>O8Cm52J?{)^-um4?eBOEY z^PcmZ=RD^*&-%KcbE(-+ij*7i?IdRXOW9i8*es%p&o>pmD{*0lw&g|I2jYf}YB+ZV zTnS0Wf2Z`DOs@I%F6^Ds@fF_{`qcm5e>{07r<+IJxlQal;etM=Qcz?=bg~Kl&f>hj;EH|G|6jVXM0NzPBXrI|rnz zBgmfU{?JE`Lxe*aH?Dx8n(*YL!f`o}H{bh-xlfzkQ^e@IvbVOTaDSb5Kce;ARYYqR z%NUq3>_8?~`X9*r-hUeId;bmpb)UYU$Qo|Gf9r`jT-8c%j>oU}I-W&u8|`D!16p=$ z!GqF~0Y{^yBMXj_r6UE7hD%2(9L3r5qnXtU3%#q)aksBg{OKCSAKI2mC<TTaAbo zdR14%tWWVhJ)|fbYm|g#uSPTLmlo2Vlr_+vPm+$WpCW_9?F*xsHH)Oa4wd?PDQHx% zFwQ)_Be<#t_x2Rh^(JZi_z%7eJBsL~Mh(84i!W#Rp57{b*|qd7eECi3+W3yFoNcADeHr%g}bw@)dl}43pMmu>}KuJy2W-qm>jhERb? zVu~N8BTp*5I8j%t;wF#x15f%i!e^uBi3XGb0aV^T_e>i3oYEg()2pQLMY zhwm*jrQZtt@=F(^43;CVZVRJ7Ywr)tPKD-jT*0E~)y=o#da8u)uQt>BJnk11&WE%$ zqsaTrOU(s^H2x4NqJ3v*D=*qiXWP5_3;nf{H+s_1$&5ZBe-54#B`IxR*{S&YxPqC@ z0$OU6uw)7P&Cx6u$l#aE-IuF@i!~B<88C{zLJUgeH9()q1!ncN%X_6h`>62!n?3dp z#TrTG;gfev3P6v2a9fY5(PMLNdt+|VBJ|hEBHCYDq%V!{Xsx7u6)K%wKh+}jPnLAn zcIsktav`;trFO!f?H(gA+u;p%oq31ELaVVm+fL*4&p z1;KWi)W=KkG&9QkG_L2+eqYk=SJe(VH8WCCdr5sDTTx5zcf(TNd)HHW+0OZn+bYl5 zdEfC*m8b09C+w9c?7_lVbH?S$*1-&kujwpm&2&r&MVti4&c?UztPB<2k4_)-QZ}<* zBd#%yt_>9im`4?!yR>+5TQqwg?Z?FhFI@f*Q1tfK_>P{+Hk<_t>pdLBYzga2X%?Ec ztyG`b7wO4IRk*8_PNn=EV-BPQj6AfFSzqjtMucxH)>;sm^{T9hMbCswV;Z#O<}qjs z;D4mDKQac@HM94XL#92nALP>Tr(ZcuMqY>SuN=Okh>KSjKx;%ttlWP%Y5U^#x=<;M z4`bxP;2Q!Lr6rl7&fu-;4c<{My|db~5_LI*{8=o=lx%>9HKldqJE|&~WTr&pqjvvn zMhVh=M!N4h^-eRO%aS-M8_RS|4Wm&gsDDNG?k}S!+bQhUdntwwRz$m`V_sD&=9~a{ z(+9$D{U0_u0_m8kyQGLy)bqN_W}fsdF(tA-`lZxHyJ$f67VeN>}BcQxI5pSx0^@SP!c;4-u)_T zz*z&dSPxf?!#C+H=%oyQy`)GuAo9biu-@wj*R$ zNOQm-8fWEGugq40jJz^HSdI+mN+IQPqEL5fq|k+U6%oy6gamt%(A3N(X)zAR?ONh~ zuIfYB9eI7aDGwAPP#%cHP#%cdgMA45nck#D;DM5|lpEQBCXp$ov^XxG(t1PNo+1@; zu2OC&LE?r2nRux7_ z(8!V5p(53j=M;JMlzx|K^1LFCM5K@BN5v*Uk66C3)XDBwZark{7d(LesuaE|`Wa zmc2m=Y|BX!FQQw}vKa@2xeed6T;x1erAiWuiU+;Azvv6^WOTjEGK$i7P z_{R-f(ypkw&z=}FGV7XsB<^XMkp(X4$bciKbc9rQ1jn+ zR_4cjd2?2tEJh4u)+Ubjk0otKZ|7kYpe>IoBndBJ*BBXaFyTdJQ8&>0thkiQcYj{G zMZ_wFr8pqT-0z}Co#339;*RFzJ7)Yn(u}_cGrp>b&iMIRyz8yb>YFqE6p>;D#VSt1 zD#~lILNa)*QOr=^R)s7}VAg%mnyC0#;^?`2RDmi+(2BHsH@}DE}_+)ytu({BF&{%F#g)(RWqeyg5xPw72fMP zRw+ln z$iZbWu+iQ=0oV}h0*5i7a?v~{30kj8%3{4^ zdU>6w5EPhC5#Pr*SCkJ7UQ)D% zYL8Ic@$evo6yJxz-OY((_$2?hYp2}J(2c1mSFvsPNbpaguFt!fa?mo&;N`nj15aM| zPgv5?P}$f_d6qrkZq`&Xqh8GZdo$&L==mF!9h4`^@t!TM{Pia9vj@D-i`j+El*6G< zK3{pkPPrg@yr8ntt`ioT$>1rMceV~DB(A#C;>vVPR$-RZQYiggxk>;wvC7uokqfh# z;sIh7a*t(!(}@s&y@cFw>=}>3z!bM!DiJXnBsjfZOZ#hlM?jSouvIcS0<(sWXmC0@ z($-A5i#x^@<#dRDSsG^wYMdwr`Nsc2OAerS#xlicp~g2LGq6wN#;j2Yrsc&?wV3gL&#s)SuQR|xf&6U3BDq;_2T1CUSULn`-9 zHH~>TP?CWydzK_5Hr_{NgOeAVoEj<@oKe4XelBF$r4vZ3u92_c+VfNQTqCpZwkkKK zAm_@wLFLB&$RB*heQz%#9IY|JDpo7};4bZAv_sN$J}KBhpA>AAZBTXoA&kMt=o`^^ z0~r#jj4Sbq9r^C`&s`1VKEE2M3r~H0oL@pfgL0!@oHr;H>lnS6ey!YizTv1nfKtcV zo1djCre9{rU86iy&V}R2w6qWHC*9YsZ?j)=zuUw5!9GPUBO9<$nQ$;HMDN4#;b%|# zg`MQYD8G=CG|p1cS%0c|xfZ_Yvpm0yI!`IqpWLzRne-3EU4>tA{319`&ecG^+T6eaSe{^)+;M*1Uq z(IWiKGypRGi4=;ys7%foOT__&BXqVz>gIRiYbt!-QA2M0ERO#>|EvooUhVl=(nUA`!>znm zchLNc)YqBOLRkjw>BW#ALswa%7fG?2C#|KHwbZA1_U8HTUEA=?${C@BOC|n#i)9_G zx{gCa@_R9^47js-zFu5mrcpt@wov;UbuEn%0qZ>rjWI(Kp0m>2kR;(*E9CvzTb=R% z$qV`FTj23YV8VIaRRuZ&{QMxP#v3FnEvWucG6!?d9N^Shw*gs1|71n9A94&i%jbwQ zOd}BkqRt)c$PuTRa?IqOY)GYlaC_hp^`!KT0|NaDDMO4mJjXg@f~sa|6js&&h|{~bt{d@ zg&f?HM5$c<+DYKT{T=o~Eow&2xFdULElKQ3;0?XwE$I}sM`)i_#pqT5C(7hYuFbDX zmF|;-?-7xVyIGU1bV-ohF z*FD`ez@traw39WOms}fDMeDGI>Ui#d8#q_198sPI~Y4$$D57Qcazj z_dgMq&XjGQzf!{MK75N6)UHE4e~fPjx^LmzOVHu3gzlc|@@cHG;prnlJt>uWHBW}P zc*keFR-Gs;cQJgFh!{^U!kutW=wSx&xZ)5SYRTZ|4#Pj|Di(N-ol#`;rUj!3k6b69$)k7~<&RJ)(e zkM`R#QT!>-qKR~U*pnl2P79Y~Znh^-NFb_;mP;^Susg&$(A_JY9^$397VN!iYeTvr z;~&-V)%%kq>0Ut(>M=}U}HT7z1(fi!P%Q0rj-pq;Xkgn4{vnIkqV{y|%&c253G%@t!WJUoaw6qOvOg|=A`@k>r5hJotOKz zq$NBLh|KOJwXr^!%$4 zF6W&@ZlV%n{&C>5{)A`7=5k}5>#3rq+#@Yaa+8^Q(Y#f3F>hPekrqC=1RM&@Z>6X0 z(P;qHbDrg++%p~&6T|`hDkuNVL1P%7b1 zM&%HR*bon0#T{vhVDx5s<(!8f+~vcsKp!lTrJ^WEf@XrK7Js(iD)$h|ZGguxG{r-| zcaOf&lo!;hrWm3?ADIugFz6#*ciJ3+47}`LmT3MCxRhB!Mv%6{mWSY*YY=MPrN077 zk72Hw{GQXFqdd)1^;<-(pqsbz*{Pb+3DvDcx$W$UmWY^bqBlY;wJpmrZ8OWP(TE_S zdnU#C)55H0F6U)q%{a_YhEeslZ$w>0{>QPlxPjc7F~XHxcJ*W-kB+N-C)~rkUFVGzKIO4vGNsJVwZ*_Y_C10-er#ktPsEPmu+HW)HZXI zm}8!Uc$?=u=3*Q8lC3_EtHj>+A1c|{C#_q>^SM(sXWcLS(v*ua5|(40 zs?nH^w6Ne_mb5RbG|!t@!?%v-Xg=vP?&XNpM)TF`&D2I?_Km)A^klPYUTn=7_w%>i zKkmME+jAGwd@Xk#%O6oa}b@g@AL_1${!d=wOSKMdkiyPb% zuk+{`rp6FYS`crv|*Co5rZlY~tTT1WZr0PGX7r}NtB zD?HKSxuw{%cAi)-^CTbJkxrhxa)BY!u|0*&f^&*PAAuK3NjIWSl#}I!SEUt;cLwCd znSMDZzVOk<(Y0#vK8Z&DGq2qEP<>@CUrdIZtbMq)4deILY&aa4RtXM*;@Zy?*Ph{b zlXWNDQ?57V@#WdKVVUyyUBA;uUV1h#J<12IzS(l9O-^Z9(MjMellYUB(ha`2GM5bh z#1<>zm#OO({vCIJ(Ll-nRgY!PtI+UZ28qD)!W-;-veP z&eUi>Yg3-rvf?<_1yQ-`393V+mKCYRM?XLD#NoUkK_xpSjypl(##sl5$34+?S!uG` z^SNcYv%xEeQa(u@B5VdlC840G(WlIJnKzj+n-J~1%~{5FaF1rK8S{y@*~}W%wSUff zE_$9-ojX7{ox9pN)yfVG$dZ}$;yZrY6YsSK5Go-t_^TY#v}$Co_Z%W|&EPbTyEA*} z@4tKWn4{)Vj#J*0rxVL^X^ldJGU@xD+MBQ<)0{m98a-80tm<|D*tNN}H_=<>jQz2Q z#YuJ3aTzRy)Chkcoup&Na|kvoVf4Kd?(iG8-XgJ0)?e%w7m)aTF zmcz1%)OJFucsS36zMy5Us9tFdKSkG^inHF5pX-`jL+dW9b{&FcQW&lKz8(_WZfnW| zrTf!9qt5!zywRY6lRYGM_}Lv%#VP{rZ-2B%kc;~Td%ws{o zjcjp%_-FH0GtuHZN!XGxAM5G&BBYsy^6$rI3`{s+``LaW4?LE9)JS-LJTS#GY8ZE{ zUb9Yx*){1^%y}b)(E=SKkse&p*K0V_QcaF|znv>S;U3q?l^;ZVKXJng^MZHH)DLq= z-H@HtgRnn%?@Ol7@_6CiO_T$S^KyW&d49CW20CwR;q)IHLus_`z^#aud7$&nu1v=h z$WO)|*NbYI{3OMkH)#}6*S4Yyd2dQw&T-4A3I?;yKP_y+UAA+cSt|gOe2?j$m|N*g zZ*h%YdSHIQ2VVJw!F3kivpxw%ror{SC8A=~YNvXj(62&pa&r0wOE=;}wnVUA`*I3F znY9Ty;3L~DFB8{1Xj8hEN4j`FkI4XE{Sz&IG1D|}XgG(A-RETe<;W5|$H@g8jhvK* znyB)f0b~oZL)O;D3(3NM#0sgFYIUiIXvu1=;E%ov93)#UN4DvaMSn(SD$0S;Hr#5# zH$?}YO&2cYQmZ}2rkghv*jqZ`aOA`^KcN6Qwzfm&Rfj0?7xU;m#-VSa>38~*K+J#0 zL6pnHXoV6pVml^(j=R&cdfoL{7e0>c%Q~@3t$#*dLE{+e%&AWMi*uie#me!8^Az8X zyVboH^0q;~YJ-Q8;c8q_y13P;WWCt8TQkRbanT&{ov7VW+0Nz{0J9`7%=Q3gL#$5> z7$_K>ayikDDw%43U8M8sQO_;9_q}^tXH(uq)R@<8&AJF$!|2L$54Ui-nOWtO4(Mpl zE@=<1`q+NXvuc?KJm3%Re_i*%M)9!(#}P%ND&paXqZP)?PZn;+`v|K}1Z|O8b}`pm zzV}<@_+|v-{f75@-==@%qv3HkIZ{heg2a*jJ(t`=Tpw6C5g3Zu*z!2yk0w>8QC$^_ zS^w*rL%)%iSzI%Uz;&QTL>D)o=x?vnc&o$*ix={2;1L^ThSn{XooV+Rw|TUi|32@y z0M35(M8JL4jp{Vgw%$TvZ@7Be@*cbzy-=TwJYg3XW{cYp&o#@L!hE60ayC)eGq*-O zajmk%ss$&*khnFc{~?X=K3hpjXBgpCy8+TF#zW6Y%o6*B+->3$nrdV;&2}~wtT4U+ zu6Hk$L+k#MM%(xT;xvBj(>X7xY|4Aj86128yc6IVTAsTlYoRF%bLs66?R9SktwQ!Y z@b71e(06uYbe46$lgN;-O3nZ$BJIP4t@f3WoQ@*9oUHPqnCaLR4BDgQj;;cw$pWSM z&O^>0cVFnC)TctjnxZt>=AVIgO)oU%X~dc4Bh4gcS+mWf*qmj*oJV3$ws1RlIs@c0 z&+Y?-lwJEJGAGw>k1n@D^W*>lZ_Tq$r!+I4T0MHH1GrT5)tLFTw|?7KOWL2TnrlDq zw)TG4yjAQgVG=Y3j|hJfMwR@l`MCS@-jU7UwaE3dHOJitd(YCNvM^l#sQ1X_3wd`} zqAr0K#Zeu3+ZNZS;COyjS41U-6TA^K7tWgm5KqR{AGgBaOz(|0ZY z0qX#VyLUeUnav6u#UUc3|890Yw=Q5eEDJ1T-EqV+$ehc_E@%!DXk3jbBXmK_jMr_*pPj6P{FcABf~ZXcO?%;KJ331*cFz6r^)KyHqrm4YidEC1FJqpg+~{*IlFAFPDPD@K zi+-DoQT59(HWeJ#8X}W9VL;NV<%YOIWTk0oE`=--GI#@e`1xMB&`@)~>0VH1GWR_* z0YlxuC5{!3wR`ophxM9<%x^SJ8HoCv=0ks+RJ?ahiRr>oDa#hO9K94=o_qxkq!%uHW zHrlD+gkqwi>eXx(V92I8n-;D$rerCs%ft=TJ~@W-Fws=TzRXPRv|)d&qc+EzewHtO zQ;oCGWw1u3mdMMp0&0jpFduh)e^$wM`T@{0O}^|nE0!3S;~3=)3vxYokklsbOH(U_ zozBm)rp6i+>cx*wN+P%rLUe8HuHYwi4NQCbsC5|MWIg7|D#SsPwUjs z^}p(Ltt&8H@dtI{P^a7L^Zid4``9=!f1ga4_2}~IXdY6l6Ei9HW?JUIdu_whS7*@t z4uCr3*Bguzt-mk-e#W+Q{suFsuPzpH3z9_XZ@qh5H(i->?Znt18+_6`r|ktl5odLR zWA1l$(SF0t73(K82PB#Pt*6vhtx)5NrkimrjqZK zGXmqGf7SkKLpjr-e-xoDf!+CPCr=dnfCuBZU0VgKq!jorzHSV(PQ60@vnowyGhQLk z9g`5MdC3xfwQak$AqO;J<<;^HWUb!@X02iayO#PasIFON zGYx#T>X0{ENQ#m2P2N7HS6_8dd2Z}yu6_MrZ#QXDx9N@QSsq5U(er@8U-Vl8I*eS> zQ*6vVV;UYj5L~gW{m8;1_*Oq~AVJ7#+XX$bZ&$T02svX_wPu8zvg*>cca)TD8wB5gOwlC0buwQhazF`8aDQ$B={<9fd`g#U%2VMg1uvfyKv+-VoF3$Za9l((3!`vZiv2^_ zuB>GUo551w1v8!7egYqM`*}OgxePviv8iGPD|(+f(ae)*h5#R@*F|dkWptZV`y$ep z0w1|VM5>0j3nRg)$^FZXkn~((0Hm@_?khKfaIBGzFWv}D_w&`B@j-yG(f+vT?(X>* z<OxmQQb&D`l!}vx0NvL|hegh{gj0=6 zhCNu6f15zyCjqc>jO@?f~Y0-7h5GfBI$4??<_z^@4@8M#u%&tUo)K6ZI}b zYB{tXYm25|A>&Dc%x1bmwvu?S-kVCZWkp11(T9SX!ejLYBKff#yh|R1j^znrXzj4j z_w+7HD&9jhZa1{plryB14(nRIb3sm4|I}aR5dBi^vvXfPe^^{9THzr#72iB&A$R|$ z!}Fpvx*Uy@7+0ugVj8*nrezYmf{5!K*c9a10v&#`G{i-t-`Q!D>X+SDzm3Lct!czfxYRC z0_cnj%Ag1T0V}N>Glj%2bLP#}=N`eTjY-yL5$)deJ$H;2gX{4knY8-G3OK>wN`f{j z$9&2Dh>&N`ji%qFBhK4z(*VP-B>4Y#zcoR#LUb~hMHVU~NPTy%r?2mpS@hyeQh#!N zMrM2SqIHwj`=sMe_r7jm3CE(>k6Ne%Vgz)~GZ0hhn1xBsF~4u$db3^SXjkdYb^)8@ zw2z;i`wx4V%VHQ})42>OQ&7J>77`!aXmpVjz$#?5wGPo7;5N!bS$%MfNfGXlO9 z7Pb47Ez_v(Yejk(}AbjAocU&Yag!uGUtQlY)My6F$et$tf9K{NoRC7({yh6TB4+1Sr;UKVNH}MC-0$<)obm|Iq1`QbDxY}(tdwcp!Qs|1(5sRt?j9{ zQ!GY&NhU0Av^5lwJ4{tMqBwUpp43&ffIVCc&Gzs{Cl<3+O~>LyZ38c!a&sF zwx>q+(X1G$E#=k+GybW2aMFV};e4et5G|p#aCe=yqo&|AH{_Hr@Rr9WOtLM*YHmsU zyed7OOPrLQ`&ZLr18c4m?MA~oKyuq<&-{&HWSv5J~o`x`&IYedM)~Z!9I<`~U9qkIb%iszq8VQQlW{JV?8=#+_ zL!nrokv2n-3ie%qWhN)m)f?u*G#UeL>w+iz*Fn=m{krH3xCu@29NN}uz|429A!Qts z5CUs_#3xCi{jgM|JyEfs+~@?xP^}$Fn1=PiGIMARm&=Ufvgn+Fd9HwUaJaI0L zmRc92k$VD!HXEHS>e~FcKtn;zXA%sHU^oUTq;EcYuFFdk`xl)@te@VIRO3Qi!3Tc( z{hc;WJbX0_b*{C&M{&g0t`*WOzjXo4zi{5N!}vDpIeX9qGa2!Km7rzx$rTg=XvIe3 z>o@PZY_FNAR=dV>SUfGCSZj$fwAvsICWvp?V!`v->+rn6)np+x|pcs?h%VeVo*{p63(Kc;-(=jb)X_1hnN_&-}#k?X#=;+M^K%!nc^VjkYI2YEPy; z47jwU zIv&kBlssrTtFv)ft4AClx^naG{ih@<%G;9CpOV(HOZO8k?bT`Er&6yFo(!YXhCyd2 z_15GvV>MLjryXE+OEg>7y!V=ANx1DZ(f3X!-WeiED281=ODWLz?)BHt+tr{$#n;c+ zCHlZJ@ga1qk0=tU%}?))}ln*P)u}0AEqqb__lU)2xD?2Rkj;F8KFplFdTQ?#G zL$*#nNq&=lX*^>g1E%!r)6W@V!L}Y76Z2R5GI5;b{|_l?BCLq@+svv%bUmZk2g#Ya zC`K9=636+vi-aTS zf2l^_Nu0^o;DL`??@5olqx@7`oK(v_U0l`OlVUUGAuiZxSc!6L38IUB)xtoQ&rIt! z2fHrasGdOJ&l&9c`35VE-~_ZkR-h2*qjKFI3WJJMUI=_;TW@D8cwt=4SugbPHoGR+ z^&M7keXF!Sc>rU*;7)+dyT5Ds^(&{m>$K0YSHPb!8+#>S7>M=SUD!@HP+1Kp;ZB7g zbCPHkhv*uc?(_FW2+`>SGq&Ee){Bwg99I)8lHpN}8DgWK`a~>bP6|-wDy$T?dcx9a ztyLMX*BXp3nMxrYIzB@q#`xBc!8RRaEMR4YLvHI&O!-h3fxL>+JgkJXPuVZH|AY1K zOQ;iFTbi(^e?JMXeMD5b6d?**h@b-3y5Y*pSlU7^ZpfcNe{Z)}^S-$SGF zJ=SD2|I`jkHu(K=%jUFiAuD6_+tQ%@f+Z26HWi7{{?_fj>pO2=@3p)OssBTwA7aqY z6sO?rCJU3a*ErLhd6vEb-3;po-NQ7@jngE1y>80~*GBz?(E}T$)f2GsCjSF_ILm3z z^27&V8~oRkPhh=TjB{-gDcNSUU`;^Qp7sn5n}-&Ngmrxb9Z+4{TC5|9j$$)P9FNj` zJUh9%+me?)&xf;pD|&;g%F<_zn;WgWqkhNt?~K}Iq+CFzV_NujwEfMR`GYp6y?2JW zmui{(oGWDPdFFx5Y1|oP7JQH-c&vMk>uu!jWA+8nUH=82=d2Hj-`SBdaXhtf?j1kD zx)VBaCWcM4kkjtQ9zS>iEVLq%Rr1%KYL+vPx6_t=a4m5m>r!@8NN_F#YpA(bvhqiq zoBXLYWW;N>=Ov4ouW_H+2`{K3cY7hic7N>|%p#D1mA;$mGH}u}Bj__T?SpTYGRMBh z*xT{vsw_Lj8h2Nsggsn$zPS$@cGv^&o^2m+^9_PB9 zDYm^hrek0gaJLfYmQNY-??VjHVm}Yt$2k5Jnw_MN&58fVaz>esLXitg7+o(KiuX0f`KjEPp#mNNYFlS+q{5vJ=%3d zf^)PKrKAD!^iJuz(Rcl-mA*^iPv4?a!7n9<8E$+h?SJX{$bS11`|M=js{(=VPwxX; zy14M=rm04ygJs`P4})C@14$`S9_(Dzo#~hrO%N-do-1*EwQ&`26h~Y}&5s^F@lEIw zRRVYX-&hYqJJdyD{*8#z3gPB?E!h_cIpVPM*y{FG-!KKFGrNw)yaXGAr##BKGni4n z^L$%J%fIGkV6#;3KH@1p?(Lh42WdPR4}3pV!Wu-a83?`Cu^ts>Z*Zi`#=x_YQ6!2f zrqgcA^+faNJ>x`ZE|Ul{+BOSe9wu`a^jE@TAIw*M;s4kCr@KvE*=!dVH(xPjX_caxjTEm#G60b z^V1adgFMUw2{nkX;bF#kzm67+>HGSBpuoOw_Y`$14E zhk1c{2CxbVMGZ=g*R6G$vh=roG^|giikOK$DN(eG3mIrt;aNb>xyKpIU9+l%%XXcM zQ?f3O%`qKBMy*$@8q+TH0&~8^_=8nl813OyOtL}awp#50CQitL?}L(k*RFSQ$fWx3 zU_tnItJYruuQz5Gl`J6B@a9*n+^_}K_L}X;!@(xfTE}z-w+3|jw<}Y3q5fMeH|w8v zd;QWfj^72$jYsZr%M2q;l=Q|JIXs zl`zZBBo4R>nsvZ>hxkUi;8i2^tzyb+f&{Dd%!?JbH#l&%~tu9nW2_WOw;6s~_!|2p?wI znlHFlch0Eyj%|mHht4X@s@h9HgVsJv&ZpM^r$$gbobJ()>4@M_r)jr(V}ntx*Dd`h zTX^h4f~doXTSK^&SV58aG>VfWm~rY_@3|XXCcTcV%dHG??R8yY^(hV}#?Zz@ul5*R zb=c!P<=f7w?Moeu{M*iH*Ono7;kTWC>R9cuxW4Ut+--8m`7}s_r#obFMJ+ACj&Zyh zb`f&K8`B8<=)s@B%i-!aM45+dtL@l_^&b-FapF2CeVf+U_eZIl?7Ua!Oto#x5yghM z)?j0#R;W0%Isp^_zqHnF88ja~-7q2FhAyv{}fXphC2o2dyd> z8}fp!uS_ybU8@*#$wr^gbcE^d+)LWSd!lSc2dB$)gwLVhrQf6P)B4bQ(HfCqa+}~_ zhoX#ZJoD@&sXj>ptx;c@HTK_r^@IQZs#kCC{T}Rj!iE3wJw(zEGyc){`o8;@JH87k zYgOO9+uE0n?+yJQ-SN0gt_vG~aeL+GpD6W6u=hbp)wUr{R0!Z9s>$8v| zK4LZKNDQ;R(f#lhgAQ7r7?r8fE#R2M@U0fo=r;I{>u@~w3Zuj96R4X`Vmoa~g)@846%V!vnq)j|&YlKn#=eGm8Wvr7yATzI`E>Ll8gKY@V}w<;kJ5k*&oWLnm_0wU=B+e; z>wnXNHY;qcB|3naFx6z_G2g8<4iV%+EaZ**YKT)7%$$EAEzH{A!+ZlQ58UM>gripaD^@hiUKQ5DZhdmpQy3qiE>1Si#>c{+I|KX;B4ca=^`I-*a_C~2d->6P ztoQmCozt#H9iZ>fXZxNa@jqMf+{on)j{U52YFoPDv(9O)0jb5ETia+PnR?YyqoTf^ z=sQ{0;7;~x-G_}I)@cqv#z1Ql z%F9+5AFNLo6(iYBKhH!5&+l>a3N_`{6g+&{Ct^>Zjj-;w)4I_*>V$&^`s7|G_d8F% zXX8ifI^~`f#!+-VJ{VuS?)8nN{#s;MqZL%~DoNOB`w_m8Z3cX4)G`Ol9O<0Wnq@fB zISurFP3M+Y>dk#j^}6xxQ^(Lk#-;0Id@W1|evjU##QGKaX@!IC)jun03{h0BjK06^ zkAsE+o|7MjyZk}|tl^+ED`8tP137mTwfPh1)pna}Zy){cquqFiy?TXB`?hm>$G4r2 zxtBW_euaaP;k+H^*U0b?8yOZ|3$BNt1|xW6{f(|w-xUv!bPjofh6xV|xW~QU%J{wN z@RN@+MAzzI+u=G$;%To%*M1IrDB`Rqbnfx&3x?-0FKn+FQn;dq`Vj}aMt16F4N({1 zEEd{I&5eXv!_?t5P?Ad48V{H~hayC~eHi%GSb?4y(^D~$68DuzeifnKQQm6dsO_`5 zcF(oCC3EU|VF{uMj!hr!8*`z)F_&!%hwakH+iYmmqAWKaGNMeYO60^9xluLuNUNtO z4bwz&&xH@SwK81a$`bJt^aV9T)Ae_hdOsxV;n4pj8q^cMYY9#c-WgP)+Nlzm!SWK> zPDP1)2js6q{_ZirxbeG|fHePNQ?7DNR82qWOS251OL~GR)NHulPQ?dINf09HZJxm0 zMPf1P66CP|>rE`RpK*6|#fv-bveIJvdG}j4W*pZ4vdF$eokKZK73_S3Pa@?Ldq z8Dz5X+=qr(UHc|vnE4YptXA@Ch}Q3Xxj3`tG`49T)d)UOS2GhZXty!&9?ze^;+MmA zJKhmj$aNL)&Z6>Ro)m-V4PoJ=NMT|6Uri^g19rh)N4s(ci3t;@Az~n58Qpg+5b9@< zgg;wzvZx#{M{2RG`1lO9D9=qsEs1M`loM| zBIjpsYV;5@(J3IYh!IAZCJS@TY%wWjbX>9D4yHI=sGgt`IU(7_Gh3a=wq`BAi-~{w zlnnaVWtQ~xiM~FY=EH=iZI4MBTkuv7kc3}sJB)LzIk{1&(VuP1Xn6T1Ua~)gnrwyb zG4NBi zfs-wmDex63)QX~DGUBjTPXJe)D2v_ZVvq3hD*9XKwB;f;VOvV$sm`OU{ z+Pnq+HuBL-thS+F#&n&mjN$^d<@tK@T42P_oyp>CV8d%Ykr{=z=>l8aJ9_$Mym;Fh zzs0?!CnCe5i9>IBtHGA)LU)D;q-3&k$cXMp{eptF|^szp7*|UUo_?@?&2&{%TW$ zM@p|zLQrR@9c6^C!?1V1H1PHPxBz z+n|MDSfY<`b$IrwQ=QF=-h@RkyV}yWU@7jV;x5Msm(<2qVDp$~TM2T^xf|IvT3GEs z0@|LH9pO6V2@OecaG^R^zA46)pOWbcQ7TQRA{keZoOgylJqlNYzDhFDL!*Dp-*cb?f5n8-yOeXjWUHrnL38_|GceO$Z=jOV7vU>Oc(d! z)-EO{#B@CpTsHTFhU)t>3{Pkn%z4|oln+D=ctg#WPiQ56ZzvMX5d%{kuPw~L*R`Fjmqel0{gB((*jE5&gp2)tb+fveLgL)erTN7QqhrOQz>O=6%F=w;`iC74Do=0w zA@OiW{^U34b6kKwIOj!C{!5KC113{Yl45Z^UBs4Uw*PC9UO-0k@!IMSp z^j8?*E1c;lRdj?*bgU|b$Aa=>+?kK7pGNs@n(I_5r^4QpVYYV3?ygtMx|kPDPCtH- z(?1w*5)K)31`WCt@~DHnLP9@v@;rPGH=A+i-2wbN4}&iR9HT#S26FS9eiRdvn$&!W zvWw9forH}76#a@PK$a931jqrBZ1Nt#3rRp0khJ(dN-hUeu{pKh(86+qMC`|tc6m#!@Az$HFPT^>9`jJ7-fMC4KQz+H}iu@~s z0YyU4>%3*a!%kkQ*02@XC_$|u73}I99DzR65oCYq?buNng|?1IJSSGdSEBF3V67Cg@wj?x+x!BqoW^g=2Bm_neD#OUrX|m24YAJk+4y?x^lg(vrCBen zZAmC-8$*U}q24oGZO8iEY-xIjCFeiTYF|>*QkX>0kU;6a-?c_|_43PXg)?hI%`_Ta zrtJ92GUMV_!fdY%jHzpT%fgm3+T-xA`=W&#>HP-tP9HVlHh}IJKzFpDC<{PQ9^$&> zZJ;QApeT=%E?)P37nu*5@;qqDbkLI&(36<{&R}`A$>{WB{{>uF`XZ$QuP!=hTnGxl z)hDACnxs$c%qDKb*dU{WPXbOcUtJAn158J*hQ|b;&sk^0A_iks2MQd?gYHZL-3i^& z#byl{dQ2hj3e`O%=qBk*2Q}QLznbR4Ka5AFKa9ZSce{vzGo6m4V=ZhzYAfMX{ssq^ z9~H`i-f(;vetG^9F*&9_Ur(enPR)cfS2YGlSpHn#UwEprRs)Zu0F!9%pA;CwmNH|K zJnVy|6l$clV{X+o@b$~FSXh$wLTR>JY#}fghv8S1ng zTMn{8MAw-~MX#YWRlA3r&Y-Xy-+V_e(vY z7yB3YE79fVK$4u^u~Ywf#}2*UnuyiQy4Y}Ag&57%TmzJJ*o zNj-Tkh=91i!P)ee0if>SZglLrX=u%WX~%%WsSa5(@O3)y6}BS-0w~qQ7@B}Fbhid` zcfTZOBS7QAt3iD~LqYD)o@$n^4!sQP)U1AB4S4M-a_S$(Fuk`p#ooo#YAEW;)8a zREMR28OyabhEG>hFR~PjIJ(+a)H34+3V|gJA^j@i)UvhX66D3(YscyLw+gJ@(ewhI zEqJYqiD1k8*Qa1sIqbZ|$u_7pTQTD(S4R!t(fjA~>AWK^GddY|iz3Bg$&ZU-OhK!k zYyTym+sK%{Q5&5X7M;Q`OOD|eGepHtks)jAiP14-(J@@Z3{sE^+7et6$f%enFp@*_ z&3L*|ZAfWU_b)f3JTbro>K!3!7>23Wq&UJC9sy;@f|p>iIxnRdB{VO@en8~f6sJs9 zuXzT&yIL47$n^t?ziZJ9VUWK#U`=>&%nnkbDAw#y6)VbBWqzf-ZVpzn1U64YDW#7* z>)E^+b3PkWik2^aQ*pLM_i(D?%>oKJx|(Okg_cjzu;t)eUdeU_1_qYH1KEE|mtRZ) zvcv|4$~M&xkZ(%CoE*04LwMX~IUNgM>*79Xj8twq>~wHvVcon9T8DqagED9nqUNE0 zoBmp%NOinX(4{Fbm8;>uRIr9px?sv*1#>(yD9%6Mh&g;p!7=iNIv9pi99M%Fi8;=n z76mey4mSD;&BKn+m*>Mbk}GdiKa9D|`&*$7!P81*RMdRurROzFj1PAH6_np8R!;)t zCZ*J?k@FFpNErB$^9!ef&xL2Pg{gP}bYU8$3xmnvzu?%KhWwqtxoBgAjZ{F|TQb)g zR}qF*rZ|I{;Q|>)eGRF!$}0Rt&=g0l2`|a8$6-bdY>e1IAlt^tBv9<7*X~fbwjok@aFxxHEvu2A@xuazO;e ziU4)eBn>$5UCXefVcQjDeifw?)O!>g&w9+&A>Zw!bVvGK2a5A1w$14qe6;%ho3uK< zXfkO07>Qb!{KhW_ba(7@;gVg3(aJpdm_s2$oiMXJ&>X&D8}z|1S3NJhgBCt7M3g~N zaqTQd9HdEYdHz%Vnc^MB)z-k&w@&nN-JvC>4sAhQNA*_ITs_Q;?o@cir{-Y9O9sY6N)n7QsLo2+@(d13Lu zGWu-bpfJs&4%I9Er3;*a!NuxFF|xeBVd?-pA51=k#?I{gDL)Jm1MohlDEqEu(4Ilt zNeRUnQZaFVzuRO}8Ho9uS#_g1ru4KBE$nIz--s1w7E_@reIg30!mGeTW`eWn`IQv^ zB7l7nXIuP6(phqR``OBv(vs$L?w5M%KSnO0kGykQ|ARa^5zLZ*|H~VXC3% zCoIRi&%shJ({)M-i}-!9wHo25yHxTXU>d0Y{lERD=+#H@-jH+(k;HwnL7OD$qc;xa z=*C<`D_j8&^2D1FCoP$Jn{vb6Yb0|t;_ea?tl#d6r4e`|_*O0X!QIhgg~l45pVR7E z*wi}2!CIE3x(SWG_>)1lyCARh=Jbj1dHT_8EKQw6YX>|KU!wMNv^@eFg~vyGXuk#) zrq*P(uZC4u6e>lWr>sQaUYGp%A@hihkJ4AT?BURpbb6sXoSuRj~V$UkbnP$;Q-pOQGCwv-o)^eiGU|T~7 zKT_-RBa2PDog|3eJ|9sfm~{u-g)N~IlQ5GMVhn!S8VX1R zNUByM59Ui*D3v7%qICpvjoomcKrTz86d|M?gS9QW#{f%;taP)l zZi{ohbu+l$w?w0M=$(H&0UJf9`_zph*jg>N_QGf4hWlljT{d=Hg8^|JC*u71u0Uia zfJ`=EnyJgI7L=~Pc6Ny~_V^`}7(H~tfryW|+sOsJY<^gH18x1vqqL4iNvGVeb+S>* zgyOV;4QL1K@FyWB@<-PDq}m4g##yC3SvqHZ=kMDSrSrkQ^LOkqf=3){KH&cJ%2;tk zOwn|eX%=ExGKthm8JV)e4!A$OLSf+%d)=frMzZMKIztf;IK%)BOw56x_$aID>;gzZ zHD|)dGRUp)d{q>5_atGTb(XLlkwiqq&RSw;VJ|kfs@2{H*~>R(!*_=9zhZwLcV<>y z!X1w|5_0l}8w%fdtmxClh~pOkeZWlgV>-66*jQ}k)u0*J)4o26<6Y$pSz87f?>+{e z?TTJXFBKSf)aI4ez3==^d_F4SGbFe8qxil24*bsh_?Eo^z5kW(c?Im5NDRDR(P!`V zko^ke1Ecx@I*P25y4noG?8&~_j@7}Tu)t@WZv{g`IBr}G@LxG|5Y4_7Zs@d`O$*c7 zY;?ZJ7wGSA+mCECw~hbv?z6ra0)6n?c*p(k?zq3{j{Ar1xWD<1`@8SBUw+5^jd$GN zaL4_>-*JD;9ryos$9>}+_w#Tc*$C?r_ucbwx2X(vSG-}c7`YZOMMFpl z?5FOP?d*2H4X@(BGkU4lsYPz2uMh9F4Zu8jwna8lZ}#6fB>QxvqGDTC$i~LVrmTR9 zob14gZQ06-rtF{!eNJ#iPL5y2dpW9&Tg=BIv&|RG`mDyt%Q-n&VP$7q!u6pWkF=L?TJg#I}&ArP}t`DqGc4srEptt=&(esNhmLR!Nc821IAr|Gy`o_PpEDAX8V-~JF>E}vr*cR@mV7rAt-SmO03ZQh!r8JL56aWmTUyCaMZ4y zz^^3j$si{pgJe+acgX$*b$jO8Ir%MLLbNDu&)6E5Pm_Q#`8@f zkqAyLyeufJGMm^D(2?mUv!iyhD}vG|o!zC(H;M)NAmtJDW~MfDeoz?ZNJpJ0AE|AG zBcFImb};a6dJ9xZL+6pg>@fkh%WYx5!hSw}q&*Ag$LCTR2TqXSGT9(gA{-_vmh#jB zC#xX|E6`@(ejR=S^tA6wUqdH8xYXaa)|1W1cZe`XLw<$yKTi3sVqc^66m+z zgoJ*VLB5;lhSGkhr{5Bmwv#m~lRcL?$QL7J%JYf!#KuWzm%Y{%wOIQ!O!*;vM=StL zY`XVU^|Ny{?3P2t=&|QSWd`j3m-!v|_Pk3uj2~v5>vEwbG{|?|1D)!!e z;er=jR&1x=*&Wf$*9nE}O9oAo56;bc&&!1}N3kJ-omMYmnbI>#+GYi^SU4*#JI_DU z$JilNMk%uj_bX-gMd3>0{7A<3DWCKk?U30RM?i_#7T|~mT8&~Ca5))fr;`1YANN}b zz6&f5Eu)izcJKF=A-EhpgOlyM!+Il=qr>w8Y*ZYv#tn2xZ9xt{+avCoUDv7(kkx!M zX(z!v4yT=qRq7Z92w~b3$`e*dP25a8L7;T*p7&ed^{)JP5v6vwGMk7`D^qpxwn?xA zeWE(mZU3(rueH7nG-#4`qnVm;mu4Ap40uT|(eGqJzx6TK-%X-%Bt{?l=tMW+Vg1GF z#AIB(9LT%)QJ+ze9eL@B7R<+)v+Y z)jso1H_3T+kIn7HN|~%4rg})*_EnPk`KFupj(`=w(D}|i{}12303Wv`%|Y0sfO>O@ z9Wwha@OLn}lEr1A#sItBK-W*!h#>QZ?sOtNGM6upP_s?^&2}G0_A!}bm!ZDvyUJ)* z43FIB`J`SAMwqgmK`rX9Pc!{@eTffC&?w!avdjFR`=+_$|M0%cJ^2rJzkxeU`U+Np zNXdR3`uXZ9=~IT~;ci|rFpjjQptQ>G^=_kAcPPj?)=S~{Wp27Y8gbO#_uh8H2>3$i z_x4jw_o(4mE3f~=e+CKsP_Nu<{rE%J*CH%Kcmg2_Aq3%r{lL9PSc9+>!HA$j_~$>w z)LRH!5uQLWB0PjJ20?)^2kSYZ-Q>9L0q(+Me}gO@*9#wssl6pMm5HzpAt*xuYKS_r z1Jn~iQwZ{|_3%&K?SBu~Cun#D_i+s&RtDD)y5%SSNu0Hpzdw{u2ChJ6z)EX{4!RZS zCeT60zW2?j`}*f{um1U5&uj8ie24cm9o}TFy-$zb)q_@g@hM;*#1P-LH=Tao*=HIa zU%o9vC;y>QIz$Uza{t7S?7xOGG$I5Jm+9(zVoCMfvxmNU%`~s2RxqYbbVO2VHL}glUEUNj= zOtXyrt`!i;6%vpxs~)*hB`M)fQah3>a^HB0pXBX@kS16=4cGLpJxvG@GSJKI4DuE4 z#~M-cANT*}dXTa#?lYqtyHE~Nrl)X~AC5*FM9(Qg8;HGaFoe-TN(0M^F6$hWM*i>( zk$ePc1(f4PKRNL#n?_`W{Eu=dQ4YdwAoce-=;I*qshy{Im-ma-=KozLG8PnlCx^=; z!}Z)=G4Q5{J=$UUypE%*jJ5_s3ep5L+!wO9$wxrgMb zo%F1QLSV~JK=J!Q7}tW)5_pP#&70PYCJyUA9WtvkNKWm7=E0J{OL|YD&PEc@C&%9vQ*%A_a_Yz_eu}rW|2HlcRlgPAr2r3$ zcxN8T(%Oh-6`O$5*#6lTj*gKxkvkf972N*11Ze01qbK^aU-F>awk}HL0l9?L_R3&8 z>?A4ef1vrs+zU^Nm{*6H(IMkCkpnqpc-T|6gDm{4|urKC0$<9bmFg35`1|?}{|AxP* zXNlIP(Xxs|4Dl+<^WN+8uwkC&^y8vIEzafoBnfAs_n~bB%|=Oy=ICjR7-~YJSO0U8 zhn82QCOBt%Xvthy&f%Odxdd9Br29R&dQ&u7j2H1#H|K^#@`iWw+ zJ(CjZ#o5DmlG&EgwQIQt@oTMxo^Z7JZmABr13h#gdH&c9no?Luen?eCbZ(KBN(S3U zq$ScIJp)GL_kvWHVL9X84$l`fLvs5ZnEKzjO?~&w#4P zJCw-L>QKElB@w(hNVz{gV2NRekXGa>#&(WhfLKknjDw2aV~7Bv04*}yphOWU6)hq@ z-5c8I=<7};I3p-Ukp`HAgM9bE-8882=TXPJBOlhv;S&RMVS-OnP|MMJ&FCmt{>Yli z7>EJ-0z7A<%v4MVumpilHqQIk+cq}rh+=p~5GM_B@AiAS6hquQDt3m`pL-QZWwZ~i zO=`BXYcQ7xl2VK;l=wnXQCe2;DS>}ou^MrX)C29?53S>u%N^iQ3bgNcwc(teZGzrg z%%S(Gy{SLDWF29$c(%YY_r^AnBth+wfWsvUh{K*$$8Y$(0O;5*H#Pop#--tv_AcK~ z?>PW;M#B3e+%@E`L;C&~(LNNsQ_*qboBdHoc}oOGC$aEdhZ0F)L8PMNbj{`PA1sC> zd5d&!>doO27>3F~Npyq@NqCT?1T(xPxa6kew$>vBAW-Q&s|y*_q>1%UaY~3@rMNM? z*5n;MCW{`{-Xr?|0VEWu0$TVfbn+9hSW$9hz7}(3kU_D9Dcp%vk^(fbm=p^s6GQNS zbkM@ootBvE*Lw8n7aD_+=0(ZrMlntpb8i#}A{}BEM3e(!Jw!R;Fh61@ECK?#w1r^7B|2fRM>R+$pUuSB zCErq=XRLUpASa+xR-{7X3&l_HpO#5%kQ5}2DkalG;|=+C){Q`z($LUdqNy^ACgn%q zFX~z3sJJ_$&hfAHjd9blS~AaM7rgn6M}8zF-081LzB((dMNYC4C@=ER&*Q{M5wYoc zmZ+3P-gPR?+lFbDc|fM1X_D(aiyd>D(i`3Q7IlZG=7%?TWmivi@8DcWDFW>>+8KvB zn=B-+e;OBX`Wv*2PD;VE1r~3gQKTnIETLE_kX8i^jY}uKrD3ax6$5@sCN?7l>@OE3 zF=rPbU1*vWl}$LziT z9rp_|7GmunE59#0KP`ZrpZ*F~wR}kR?ozwmycTEI7n}_6BH`=IAc9^tIC$y{zE3p% zEj$1#SOEMM1a!z{8dj!GhyHfAS57qhvO-Ol&0{_Mh#tm4+lyJ7;Sr}fiYbZApQxSY zQm6wUm-XmIJE&9M;~(Fp(IbYu3H^Nt@s^zEPMei+zcd*-#n33FLeJ=%CI2}~tNsI@ z65sQ3Z)yj6?zk`W#|QpY4%!rf&}rL>X=?vcno1}m{KUM5F>I763>cBtBg@#z+ePqs z;6*&*#&V+$O*o{@x77j_&ng(p>cTKCh{l&lr^cB^i`|ueD<7IQK*aTg^js09Ar=+W z4r<%FO#I<_-nUPNFIwHQxtopDgl3oDoQ=kF?yuekh5{C>I3rDcy^W?aiclV0J5!*; zT}V@12t#<73xshGFR6VJy*q}J00&wE+jpXuJ;5UJEFFMOTIe9ZXAm5ie~Ve^k)^`8 zrAuo6S{noO7s~U3kjv50*u|(Q#7-UXK}o2I9#?QJ!J;c36s4~>cDoNFuRh?8D2DMj zcP;<5#>dtu98dZIsK|7Q$mXo2?a;3;rJ^Mt$@cq|p2WKw{Of|4t${`u17r@`?&A=Z zrwHSsfE91tX`xiBz~=`N8GO|pPue(y(xgYgZS-UTQx<+_DKa~Yfj@GNKVC=X@C$fG z?3%@F3ENRCg=O`5e)J%*5ForBcStu6ICH%k5#{amPG{%%~EHHZ9SGQulN01{Q`C&323)xp{6nn6?c&=Eb>^9_b zec+X-lqklQm>*o}^QQly1Xk3Noxd#VyV~(ucwiAn)zeeM*xRlJ`KyuxwSHa%B%{>( zZw~pJAvIFj`SeuaM`*9RsL2hT?*V7wEdLK6u~OL4c3Zz`qbZ5e=gmaO$>zg8i}Lqt z`3H8=H>^`waAK2l^Vi_pROfi@E!VpIzebIZ+vMEav5L9yabO$;gr7j5CjQ+@ke8IN zd;eL;-;CFllr2ABE3TJL-5K@1Q#y4Y`YB>G6sfrL{DuLE(cwOX_s@c-2ii+YMGw6* zz^@R|pzq)Vdnw~55u2;tcw)@OsC`K%PNG6Y1+Wplu3_-+*s>Ki?}tR0XXOJ;>O4fHm&} zS*O@D5j^`q*jGHfnWk>Sp5m7m$@~zrR_+{M3^X~6mP9WW4W3CciqG?{{hEAVwm=&W zEWKEip^qQYCxvxS-e-HCR0I29R&uyjXxE(QV)OC z15WYJu6<8#0wx2kx#A-4Z@Q`2JSRroY`=K2?}#Dqt!$?QR)gzvt=5n~d4j}A>wrRS z+E5$Dl6&4YDQ=>3x8c@l*s?@TCi*OQ7TST{Y*}NmPb9D(7?`F${z2$cOmor?xl(J49v3Y92-W&ZVg97p04JeWC&!LM zPJw^O>8LA=J?8!#J|W3lf4udanH){)!dT=NS>;Cl6DP;f&I7=2|0;@#J?s>%*Rk)z zdXU&VQLzV|hWtHlTJ??lM(dEgTMph575!?BsJa|p+BR4Q_!+Q4qCDSQ4-!p^`n}L> zA(|A_c#|N?%n-y&zPwGXlePQMI(RFH=p7Gl2+U<4<9JKr#E#~~iTYa(YZhnh+&uqe z=bU9b3`p3IZtjkEu1&En#H|RYPg_;etR___K?pujct;4=EpYaT8G+mog z2tpWD`17_Hyl=2(BOXCa+m?a3D%)U`bjZbId=By-_7l6rh0w3L1fDgej%Eqp)VH5d znEFmSgjm9q7!JGsPdR+z)D#d*;J>Cz)Z&f+YP~TlzL#G(NTeAby7uPKap|tB+hXF9 zTzj{PW|V$R#~GWhzOIU!bryuJS{JxJk#}mF`!zivvU-;!LJe1H*oRA3IoK z_}%$u(^Ei)jpQ~Mmk3P7yRf`E%li&~0NyfrN}dt^_ITG585@kH(8IXIKixgYBvO;N zCV^35|9@78+%t^$6GScNtS zJqddsJ7%!Hx&Z08h}CN}6(=WD1?asqwfeXz&WDFnm`A?4+j0pd_-ahG#apVd?g#%+ zszYvdfuUA}6A_`i!)qsI*fDMr+!Ow*Evp8KfSMmOoVLdOAWElllUBds96$V2>E6K6 zK*S8qyTo4=g8q<4p*P{^nK=e+Qq`Huyi-A*Q}Y_y{2kp{4|UJ%qlEG^M*v zQju>LYk=9pDptGNt($(t8d{_qJFkmvGS61zk>fOYGSjC?3-;|9Z&s|X2j0!wd;z4 zo=0U3RsCsp1b5sdWW#gDGN6aXZE${Sf{r*O^`P1U8#)z%-Z5j8BoaLlq9bz1bc3BI zFf|{WP6^5eq7@_mqF@>3`OJ-3$;(a&Q7r|z7lA1e#f`vOT@Ozo&^ZdpWRLO?JNGF6&)*SKM*(^0{dSqp1xaorr8zHLQ=JzsDaf32_Gjn#Li+uXD<#T= zJ(czoX|l79<(lc|8`ni8I0;%$YtMP1Nu{umU07Zihu!NazwLJ&dwBQ+kGlA6$W6{o zx#7noXTv+i%njL;_Mq#$pljHea~vlzz2_$@nGuJl!Yi%!)PD%HiPzTI&lq*eMOK5$ z&Sy#mI zG9bHompdgWocXB3{od@hpckEtC$_I3x0@q*%y8;6s0Sb^-jScX0lh2A=r*1gloeqt zVp^^EOVv2o^_K9Ki|E&*eB({<7*zAvi-JNoAM2YG+(OjP=c|SC`ZTPkj3=niEQsrg zmm?o1&`?yF?6H+L!xiUwq`jU)+Sc<(b4RUzzP3&?T-R`}ur@kP#@4OOH!_}^y~kD_ z%Yw%dXH)Cww4rC$db`|_ppn~A(yYxqG~4~$L+u>No*=YXH`F|QFS z5MY#tfAPz!&tJ-4b?dEzwAl z>yGjd-~7x1O){Uqc)6DF;SF65604|NS0{z88Dgmlpp$m3+Xr~G=hpe8`wYw7TKR>- z7?k18CYp-DH30#1$E_e8p%CmE;T;nu`9wH>t^GNM!{%|n(p1#{?;4M zGWcbx8|0tuo#p)VK3B*^=O ziaFto!Z;u)U1(CWbZIaDVm}R;xy^XgJ<^+>ANQ?$5xmEelEmOED&~9FN%yl++fzSx zMH1eVmlitavJ3CcBBdg>bHG}GN7*XyJ(IRU{s_4t86QM`n1=8$0)%8kymD6a81%E) z7g5TogDUuLK+DbQ-R< zeZ0o&ykT(MtB|3hY}-t{V5hc)!J zD;b(9()y!po-5U~7>L9o+Zb-mp(!lgGLd`qkT%DZ+T&`&E;bD#?0axUZntfO^Xkp)z)A8ucL;PYjKG6B z2bl&r+c9>(j&Me7D^oV|7jc%PVrDp%I&zNu#d4Il{)$zJp#(pjuj5NWQKIB#;DEO;HBk!t}BqYiP*r&ebD3{*x&70$*OkMhfZ6*=}>CRs*Xyd}t_ld9d5HAh(q zQu4z-@rs+A184U|$ zWGbrJWIQd1D|Wz(d%HObvtpXdKR=OZ+9gt|WDAk`d0vsC#dh?QbLLY{8gzTQ6M7`- z8L{Yvu{b*m#&cL?(Js(l6{E&zb0~0^^@lF)!mKve@{G~Z%W>uZXl82A3TigoxDahR$e$e`zANDWQ4p(73N`Towc7mTy2ng- zmO%VW44n(%VUxEEP>^2`YA%)~^qe6|wErmId4tKvjM2`;37L+b0pwobJ!}(ra zJybR-;iKB2x-|VC>+*oNE^7yHh8GUU?{brxl)KOJWdivgx#~`1oYlEUW7V6!E-HQW z@XmOhKh+lrME7oWM0(`CXP@;Es^ISEdw5`^cl1Gze2bWR`K6)xxD8|PWrT&zxHf{XYmfQr51TEI!Ps%BvA(W6}o=qym|cb$~42v+Ryio#(9X%Tfu zeYP6{n*uu+#s^l6B-Qs)eb3Yye4RIx@WaPQw7*=+1GoHN9pWHyy^U)S4#ww^xdJad z&wqNNMpoTxOkNHeD?WdDsE1lGeZ`FI7FxkbKI$M$0K4Q(T_DBJlqL&Ets1ugQN?;YZs6&F8} zt9|2_oVb;-+(}_M9m7^`+m!Vr{T`IG4=A@AsLl@ynbD!fW7&uCBue#ZF40XFwWkDA zpt3o3n}Goy8tnU+iuM!CZXl4v_*p&TEmws7(<$|1o%1ul>U>^b%0AXP?|VlQ=Rh?d$W(_rjFUL;*n=k4I8riS4hV9EdOlzQP9N`YEB8uA?K3-t>cSY zdWLV@2=E0%JW~2sD$M(T5&bVJe@zki3OR*GR~NzmgB`W7s29Tv#&WePal7HlnWLa^ zC)AMhIORE7+`sDEcDN1D_`$=sLC|DM5U0mgki(#T4;JIZhk5^FaX~I=Z+?pmI$u$0 z$RIPD1%*Y_3p-}RMfjofVG5pU@SG@aZu3c?ZONaAbNt3ye#&FIwCe4s&Wc10;q`*^o3cJS; zaQdU1o)sbRTJq@%%2U3@9;t)IMDL1o{J0yvt7oh!NrnH*qNpiR8d8eg2CF9fo@D!%M?KKL8agI7e0+R+WxKu? z!ZIbzFRnHV%B2LmpM~`A#T8K)VWM8yn+pW#gd$eR6+yv{ttJ1jr8Hyk8o}9?J&L#x`wrKi|>6AE!lA74(*$*kpY3 zXL}C$>eJQT-FS;U_AHqxz#{5#5 zHRJ@`Xii?+n^my(Sk|$%1`OC)?_W7|eh z!9-WL12#%8YKY$MNANi?ZS_U?Go7}ok$FnL0;djVy_LK?Wg7Dz`)t=MN+XL5>Uu}`k_gl}{@qsSFFn4=IBoTLtQ{Bl=D|kHj)uBMP|~xa zXlEnO^|#~{b7!zOy&r$UH@Hy+O5v$~lIs%WdUPeU5!3^GBoK4I4)%+<$iLCo0(@Hw z-N>8ze{nbRY5o6k@54NoJIP#0DN=C}%DomcnjR^NG{bU=-gjvH1E;WN&%HCa^s76A z8`pXispGYp=J#Pa{I8CnptAZ~5mC)4x5fmH!TP+l{>P3fOjr|8P4U)0NZ%P;h%eXR z%NMJ>&tyT8rnz^FFAhIpW(gYAd_f8Xt1~V_-F#ssExQ{l@Ml&{ZYWTzMA(ggUU~Od z_PuBO?)_>MYE&V$kP{mhSbkm`TDyp&jf*UeLYMCT@1^l~e`l@HtR)hbFN!iS0~N+J zi?((N7mRgluqb5J=+mC2Oif+xe5`Z96WCL5#-m$OQq|z1%AswUF%0V``Z~>$x;sx8VK~(LkXITd^0@IZ|+)B z`PrkJj6~w`Y~tTr=iZricZ4u^T94vQhx-%!y$QTrX>_y)0;*VOSXUo{6h-9GVKhgn zLxCMDW=W|Y!}_oHlouA{5Zd#awSa3BmS+*miAe4lw9xV_Ge*-}g@mJXw2$oP;S#1% z1MiJ`&q=gYRD#`?IlJ3L+Azw}i?!Jke++-S;tN)u6omLUz&|@F^hJ|;BTl9nJAi1x z60f)Kq(oTU--%>HQ8YwWy#Lk z%n@CmZzDE5vte}+R(#B#Xv?h=BCPY#WCQ>$rR~{-z1MQ_b@O$yLtk;`;P;v91#1Y$ zVvk{G{VnBlRPr;!{gj};qh_XKM`n7gEWzBH*|qE7b7PtXB@lh`3`*d(h3W3^bY$+wJwIA!aO>A3uL%K?bmo}(2B}eJROrJa^qzlNvBPHtUK>K_OZy+= zhUh^^&+_#c8JoK%Rg<3c_S)mCvL3+t7nNXaP0k(t1~w|JmuhgoD9?bkE;o+- zg#Y$evX)|A(J3AUD2eyuA8VyGCoC8F9|y)f(79XggcPaqr<2d@s02d=y=5G!FLIG z*M;jZ2=h6bdI8UyR?yT}xHsaRmnMa`mt9s$E$LWAk5*mc=MMI+A)~JpJjpOx=GoDA zbQ!TE=&7_kO6KJS{?ooI*Dms}cmD}e7x?h)p6FhTQSfK){2k&CA6rJ|(+7RuT_ZH> zUQTM0Y9zLBc3v7;L44nY4D+o`YeaA2T;AYgV{EidPmuArEFY@u-$5s#W3yzWTtgkeo&s&1U zxBvN^jI(1ePpWDZF2zen)5&(KQFuN+%0lC0l^=hW|FIo0ai;uqU4%u|IuSXqy*9x+ zcL^t8bJwgYL+kW4q=w3F?77DtKn$CE8b(W!Yuuw3_^ExHj7zR*&?Xo7c>ErzIks%U zH5Fp5caJqas~(%Kx;M(Y`^Ug1(wOuy_nvtAqfDFC_s?(Fcy~WJzkQW(|NM3h{)fYn zlL)Cla4jPrep1o5KcfFOqA%@#feZ%sWV}3tXLf}72-lX=RLLy(RGNwR2ruGy6RxZt z=QRBO3crCiNHrmi8QC;-7-<~GH$&&3vcFW`9<}L3<7HvXUWtv+>%4hv-Sn10j+*?C^KHzZw}tnku>(O9uQaq-(%DG( zue4`&pW+za#M^z_8jqnRTb+yGr?nt=F-N`u8m-^ZtV`y~jp^W?Frcj(T|!Pecqd=> zkuM2O|0}poV*^l5@P_`5Q~5&`c9F+A|CZU`=2uFj?n>yF>pdZblflgm=$I{fU6`$t zmGJ;>|~eRGgMCrH5KyIVd|f;7J# zj1emvQbPEyeh#LV8ZQCwPVXtP%3$F}cKYM6E7Ls`%}QWTq=25+3NN<`)H8JLh@?wy z(*uK@nn-!v*0aJ+FLe-rZzwP30i77@l)(lr%@4Xi3q}A*6zvWByK7S_?DFygq5)Jg zz!&$>I2naG{T-3q6^ZTa72#_i-yQiz+Vjz%AM6T;YDnt3-A!_eNBRe+_}r%QN2_PS z#*MUBrFWNnwy?snh^9K0g6@573K<)uHh=Z*jd!rxla+8yAxT43coyqqB>aV|3-7lt zh4x)0(Cloq@1G0(y(LF4SR=V6&>d`%A6kdB_H1y`dUzZBgp(AXEUG96CAwoVtk%HW ztDrqeeS|klc`}P?u*%Ov--ySjbXik27|HpqLD&^dt1IxPLD(8idw%Y{3QG8zc)r)_ zo%T!~e8O8#7ClVL&x5c3y*S^P%SGhRfQ87(BvLa{H_!uxALT^jyf7c*ICSvt$f7i| zQZl-F_|;gcHg}z=B3!@8{V7p$8)@Z>lFhecaN^o{FVEWpV_}(@cklkU0bj&}?V9#^ zr)_xm7ojY%X#310vYyh3tA_iQv5~kU8|h!tyGco;Uki-#aur))AK+~mu_^Eg7*svk z?Q0+L;Sa*Jns?DsTlPBG5Drq;Qlf(#^wuQss^BBIq69iX=Y)+}H*0-wH$9)i20_wK zWbDTe0tq$w{CIhaQD$rjUZQ#++^5Aa#tDN$xv0Pey0#00(IpWI83Lrlfxw!nYR zfko7oy`;7B3fI2jW;Vx({1Vqh#S2-9K4tP^WSZ{6cu~6qQO7 zhrTC$!<63tp7c|_;P0SeV|4{%z0rDitY@I-W>s}wA0Ar_##N@w*2C*TS8VROSV=~f zsPF!IfM->A#|}B~1UT-GA3xXY!!10sE24^6;(01BwFZ<0skfRc-l1+ctuMd|EAdd= z0DlrFJZ2ZMcDv^MV;Yy8FPaEmZNNLD!O5J3H4X9upbpMy7~ns`H$OOK_GDIGK4dk> zl#ZD;s~$5M1=Mx zeMQ>Z54n@Nede5vG89$5?w*5|QMRTJkGIWT5!Jh{lX6|aT#c_x^_ELLTrO>8+;u}5 zStD0n_bt(T--Y%2mXC7>c*k;T^~1yMyt!*;K}?+&JJV_%1?RP+{I`rM(1OlfGB zaIT;Kbs)(!T8&-j*`Xch`QESVhW3!avy*Gj0nvd@VA{W65-nn{bcoV?4t+PN=Cu1k zZyM!D5T5ZIm zPfak1e{g`rpeFq0I)GEt$F4BbkYs|Ia1e5cyV40|{riUZoPnmhsT3HYn}l@i_tM!q zuoJRV8QLjr75WbCBF1$juA~o-FZQ<4tg)lKkZm*Tv zpXCyTki1608hz?kAQMSDl}7G0L$vb{2SrfV3~>ZJoe>EtrR{M_?W5p@0`Yb7dPXf$ zpSTrB?=alF7%7%C${q6ZNcc*XS^Vq#9iuJO_^WQGIUafiiOBJi^PGF`osQ>xp*L7= z*ysEmbtbfAd5z4bas1F06ph{QfpNPx7@y`Y3%g1JN`gyc%Z@@{*q?`&EqE-icl zxExD!=A_(=x78vlpLXUb{B?}p5U(ygxFt2 z`F6!WZKfuF;v9Kk)Q2H&VQsD0#*TY)1Xi(KCFS^=Y5hT1SmVD3IDgj5LQ;({TBIy~ zf$(4+e5*m1&!=4yDl4aLW>`^=M=SY2Q;u0KdK;@C(23xCE~eFaxh-TR!;S;S+^!PX z^>1HXK={M+#?Y~w?-W!AmNV!%qHjjUE_6l|g!qZ#Ry$>J1wh>1+?89cwuf34T4)tP zjPU$DlO?5p2{WWDKE%F2h(A9T2{rVk*EbA zw;g{jOlF~%wdAE6GSPhLZ5Ofe_qWT+9STqw2{Crxb|w@!?Y4lj;o2M(!WY1Yyc?R0u?)>&uD(-ExewcU}M|vm3 zMtcf-LL8d^5E^KSAW{*2_}`ss`w(CJPSsFNJ6c0+=JES-gpAS?K_pFd)m6sA8=d(be(AUg@rpF1M?>9rgdw++BJ^_9*4f%Me z<4+jhei1*kh0P9lXCW-$%2~OCY4;uB(~@`S3FCNU4aVYjE2IEAN9t|Ybnp^hMx8rQ zGZPE+LFABJh;o*Zo)Gvi2Btz6b*Mi`-`?-pkwC`S+_j@>ly`6PuioAYs*Ef0`IpOg2g61=;t)oYf@zs+%rqWNO>H)yeFT@n z4kWH8PA+6qmcVD?bXqWo_#Z6MJ#-2Mi zpN#t&>k{vo>1Qj`E*TZzaCq-74c}e#-klx3i(F6W(I3fOXuvy?4j*~``ZV}1VM5{Y zBxr1)#N&|^=&6|7E{!K|c1Y~2RL5{JOs_T$>C4Jsn8QI_-8?8_U*v|0J z_RCQhlT+cCbH^{?>pPFkkICNK%fR0GCA#5`ferz>C^Kp_bO1x9Ux*wVos%tTpD&5Y zAetgu*_nPMhg0pdM_q{wcG%4~vI88SwNCS{DvSF_tAF9%DeT9X*xdC^6&VflCGtix z7WPLsw2n&Ko0G+XX2)EfCrBN?wub%TNgAHCLHk7DnwR zNa~1VmGD17P1JjiSjo6(z}l{|D%j9!pxDUX`E5&qtW?wjoxz#MYGEy~1b4tsl&{}!8$6R)6lzW&?DfxEEpU!>EM(=_?`JSQpH!J^V{Bz(lOKtzTKATnmspfA6ll!%CNiAKa2*VyO}pxJ-Tg zCw)a3;G3z)@9Vvkc8zlhC9}yK<|r$58hBVlOL4Aq=CK*<0p(DyO!l@i`b8vje1)Ea z7XN%AftXlLd;T>L>wadqub!5SYYcE4tD`m2vaJ{o0(_be^}(LXac+Dc@+l?O1(b^8 z|H+Gf39$d@F2m@^tsRQLAMr;I$A7s}?mf@nbUnwxY8?JBm8!A%?z)BE9**k&&YeD- z=OW3MXURAtDN)*H*Q049F8PLx1qr;q$}}?D-`x~8UGik0uhLECc8>D_M+CR5HU&>p zF!sO0$`H;`u>`A8k98y4JrjRtrs*^CjT?++_e{hSu?u1CE>;k&@Q08;S(C!KtV5)X zN|iD{rcQTnjY+Jn$)QRTym_AN+tV7473a45EzD^-*7BKM#wsOjk9!RX2UB6V(Q;#C{ zTWokM@jEYK-*SV6aE~uB@^M(JV@-M)!MPB2i3mLlu&?53M))UwD{%c6uFm;Gd-A0W z=#|Z*sT$n-;z}WWi}zdcd_KbBOd5WH1H4vNdum2P8+2QrcnnbIJcCn27h>2k#0K-j zCcYV5DbYoFd8}nR(IB0o0!~!+;Lv+YCDJ5d&!P0q{4tC=57t#;S)C3%herNKA+z>c zPFS5^%X04F+Gvi*^RVj2K=Ti%vc!Ly99A}>j(j?xW$ukj&oS)>nI#HQd$D{zPzZ_* zN%im@D#~JkLM`86_{}Bdh~4LpHA8fS2)iVcUtFWY%I2r_aS_czKm1l{yPXqZ*+|0+ z9px`}YPGPH@FyCrq51ndbhKY=Zj(+M>!dX4cgn*)N0{r80m09QoR~f3Q=qK~73{G3 zsSi$n(5vl=wn5s-leMa*%YwLutlG2_T7wp1dmwV@4O#88=pilh1^JBU3S-t9U6e+I z{1r$y$eZrql(q0rH{tp3l*4>i4Hc)pzu3_b%i z_!r;Bn!Mj2aUSfYe3eRI>t_Q8p00D3r*3Eu^uKlbeksr=I-nAH>4<+^x#^L#kk$QuVa=s@10FklRqEgFU%6NqaGV&3WCo069NM}OP>F+51bmc zq*v5=+kC)$u{OfHm-M>SS&bI6M$a<6lE-0joS19zH+7m%L+9#bn>`+<+F3O5z(a>x z=HYY|dh}qX8+p_$7E@irqB=;p`oL797LL=l$Pze5x z16izBa=Ae8gSIT^6y5&kx-W(Aqp1mxJ889s9pY#8z{2ur7X#U-zr_cCzZ9;;Q3ut~vc*AdLSSj%4k;&Q~Xt+z^#Tq=V zyf1}@S%eEE{9Vs(aswd<<+2;9ow71YvasIg_Ak$VDLA7)a8nZ;E>h-q!PWady4{_I za;$`fH}N*Yv@C^m@igz-ixHD_7Jau7eHVv7_@so_mUo1pT}_=cHNEn-^+|%_wB9%u zxOj8BKG=AIufaTzy1W~d>Kb;5c9fH7@rNpXopZce{>CwrNG!D@Bv;8 zY|X4Oknvfc%==7Z`q?~&8>rQx1rksuT6da{LaZ8i-;77yPyU({B?{kW5H(3!b{Kq| z3NlC04gxfdDNPJ)^oG(Qx-cJM4+1&Igt3KeNPcDK!AHq{Z7rl@UjvGc6zeA?(|evSJP+Nn znhr|Z(D`B^HD0En-VEq?0DjSac~(;S8^5M+zd_t=h*U+#fQS9XZ~8kkLUVy&IWvg5 z^<<&!05tdfnf7lfl>cG*c*%z;!VE>K1>VeiWR>yYd@PR8fHqLpj|ZwV4a`OzT2rQ# z*Ux8xi~(mhrr2cdUZe@J^&aCmrt?4{EsB zdaz?T)AVsz%&Mj^?Mko3ynoJr{hOMD2mX{lOYo(|rQ1F_-myFgb{_u3o4Abe?`7g; zpc1wrzkGNFR%p=n(bNu~(%<+)y*~CW>~m4*BYH1994vLA9?WbZxdE0Lk!E1eyh!|x z=HiJZF<)Do$ihw`h>GcTIU+NoL{1yfFG5*-BO>j#zygd1%{+G?TVa^wgyv=91=gqi zgwN1=n38XdIs@Hz!pS4+^5!l@bysV4ejG4sXPPdnXQu1#jWk<7$<=St>`Oy!k>e)i zqSYve-Ubc3kKO1uhK}}cr)B6hYLVsN?ixeI1u2^i37oV67E(XBB5Dmi7pa)3P6mEx ziQec$V(UHOb)5Z04WcCEpiOa8G4*%ytEp(cVW>sode=oUtdISgGdSW6!^!$BEUjw1 zbQyLJl=KAqRjbmpUad@5-Ye;!`bV0cQjbg@b??cP{#~$#U+lKAvg)g?A*Oliko1sy zZy)Gan9|gW^x%6>Mg!OId)R0!M%a&_MyN4Cw*op@FZv(vfBUcZc#9nV`2FSn&8qYKs$L?~ zp`mj>f<4&oBcGZv2C|43A!{$HIn?puT*&J|t3aoq!V11p56;4{EIc$hot%m13v|h( zjJcg+`bYTI`aBc-H~9u5Gz}Ee#1|sB8-OsDcNkiiQrTxOG!1+oNqDWWV z>sei2AS7{wx>i8y)XP`(`~TPd2mO;4!0s6~l0-M_4O~edPaCF32~Bz@9lBOW7*GT| z8=S&IQ6H=fbxuvj8DY-4rC#px+lFaPs*F<|RNxsQQ-o)kqcbLOA;v=Z+aZ#WMjLc#3?8ef7*|Rqd=`-I8@W`V z^QLpP2FaOdqhG{y%T>3My#Twpo5Tu8CjgHGyNWz0(D-uGtMK$)VB}b)-4J~87BfPC?+{JZZ?I)INDdc?z5_KInV-edyW64AbwR%7IO8+Fc{A-U!W6YF!a{_#2mX zFPpI}xehXF9fiFO>yW>{H)cul2Cu#HE^rg5moEtUx?@>Hzhne{Z?uvXmf!>+E;uxL z&%cW=2sJvp@Bu6@DT~;n@|nOscW5zu3hO-iXQrzLk>;)IP!C5HB<|4tuP)Qk%L z%$3;Do7yf2%T)~gl&WjzaWZfX^`0=~n@2foF+&=}wTCg6V<_TxCyRYeIeodFquS+x z&!>v&Ln1aTU#KLf3m|D1ooWkfI3+BtDPtua7N$4rf-p@-Y@>nMrZ;oJEK<{n+E0q} zvtha8-vqu-K&{T04{LM^{v4L3`k%>bK~8ES&)H?|G$$B4Go?xUQdcxLLh5^4>H2tN z>`i9?%J~LK1Ygl}1{l zFn%i}B@jG13iKfr?WZBOU!nx~eA*%DcvwW+=CQpi2Vj@pn@h9b3e!a23J>G#t@l`= zBW0alV3a21TK1)uH}&R7I~3BCRK2I)N-XO~V6BSL*}yB!Q<*tp=@eEkjh07$&hHzf zStV%BPrAPqj)J{Mc|551d(eWDGTU%H2Klt!GxeqAcRgW9#qs^EahB!a)aX5z3ehSU znUF+4iyZA0KO@`WYanf;JFT3Ny)?D%^cCUPX|Rd6R$z9(uBfCS3w41dQ&Sr?B0m=` z7wwC4jaK&C$D<}<%?_KEs}n*S`m&*mRY>$-{%+M2g!@rI9my&nK4$6ZbgaHJ6gle> zb{XF92w*6WzQ|AejF&p{S+Qb;kB`smD|~1TT2}G>tw6bo`?l@16qg`wK?#HNjKLli ztt4esgtW^;q(;U$4}21|II*7IM+vBGN|ZtxQ3U z5ZC~_dpd=KY&vfX&;k7m-|djm3XXVBCqC&IqmYL;?k zz+r?wn@$Quq7$hz@BF#?d>d1Cx94YeG2qI6Fb`i^d@$cvwu&?_xT!d|^R!@2Am3ee z!=nt+4h1Fn>0FUTB^ zl#y?g^>a9;gQlhR_(o60#RFTSj0HKUk^URR%5%@hxh>W`a^lQ8i>h|ME$b}@`Z-RH$irU3tWWIKL=j)6@O+f_a>nDZF zyjlP>Jjv)gYyNA#CSkr(u(!GLOQ^>V1`_#ir^tV;_t$%=;`$KfhUJ^PB$a;GDd2W$ zi@^QIJouiPzI;BnVL9Q}UOA}ejxN7=Ey1|^T0}w9tC)uymjHJ)NMylmyj`@nLx$N( zY*Oalm>)vsH(B*#ihFXixk#C^o*+UlR7>l%T&8#Id5S`fTFa15KU_LDW!8 zhjG|)(Y$xetTTw&22MzIP6s7p0JGBSpjfF`c`1)~8Od`*4q<6&Wj5m_A+;!l5k_qW zk-eEg=KozYpxN*I-}m?Vysv&1vuDrV>%N}#tmpE5SdV2hr4`Hu?}$M7tbmF|Qjbud zvAz81?mtqow*N}SLjNDBn6h-}s0nT=HnnTdfd})n2E5-VNEuF->wl9V!hPu3ck!+T z>1!k>(yG2hBHjcQ1d7=KN~>twC>@Ne-G%=6Z&c6-JATQgSFejAo(HwNbD!D)LF{+b z4$`;(LhU~9zU-z)jlZKubKrT^PmjKF)1$8+qDNm?gnXPLO=W%bvB}U+AB*zdls%x2 z#TgH%V`r&~bAmdqf^6HxbKR6SI{!c$uUOyxf1z|erJ=gIynages+-acb5pwK`Y2t~ z{s)w9Ajp6iX;1h6E`5OU`TetZ`)CNIBQ&kY?=*E#I;T{Ci+apW=WGW(bndg#DH+Gy zRIb}i<+}T*+`FZ@VaME5ZteaDvxhXiggl=`@<#psH|Z|s$M2t8fOr3i^d?dr(qnxI z>mi7NBy#@d4ANO;vm$G1z!s{t78`80 z46o)5hXzkIj^5p>9e*y8V}MVvGk23$=Y=(ytE;zhe&8+-<4pGjPIGg@mgF)z((X$J z((|~AY4>HkgOxh?W{57s*HCMdh@kCLo)+Z50vF+$AmZTbh){GKXvL=m-`Qzwe@#wW z>a&67Su2V<-Z4NjoV^H?`xsy_7P_B4MD3R#BKeqQbf5FG-di}oOzk|p*J@Fq-v%F; zlt=qddElAM6*(*N)-F_HcXi~i0RK|bDLdfepFbvNQ*u`1xcL3T3ZPX{>Mw1fGlY(I z@?MN8xbfscPMj8|c0RH9!gVF$v>`T%a18$c^T)b)bDihTTe#Dm@45HSIt4t}j=QOp z>UU%0;z!jzhS8C?PDcMvv4}8p9&^te5ABb{b#jD@|M3`&r}j_xsC$0djO*kGbqgJJ zelJE`P5U)K_j*e_@(ZviSqEyBDLCAJZE3kLI*zwQmbP4ISxSSt&n{;YbB)E z8#0U09^G2RWY`8EQ8@;k`?dszyf+>eN@Jj7n*=O3q#F}4aJXL~eEfN+O+J8_3a8T( zxr;aSMaXpVu}4WmNMhv6hP%U{1}}11YiI z#7}WKEX0;CL~>b1CIvCAtmWc`oQWUnio_Y}E;MU}^=DKjeoc>B9|)~1Y?;RYf;Z+0 zF{}wVf441~R0)}nH3^er#F8`#ixZtjih=SJw_c`e5OGz3K|pbMV<7y`=gtostc^Aw z7v4(E2oc+r5{b1;beR)bOPS-a0zKaLtQOuN1C#5;;98v~Pc9q!a)JMNJbrb1iHNOb z@Eh5bn2d-JQ4x|1NuSK<7k;SIAANNOef1-fTNV}pMBVL=XE}7xl2km2*pWc-H)pux zNAhN>LD$$y4b!P--11#_w=Tm|g_F7eXcK|tCX#=QGxCSp7}I=V@#OfLkL`=43y=eY z9MW!(G7{&>L1G%#OrH?N2LO@E5H57d$=CjTn^DE0D&&o({C*XPqmdwZXUP zXZQnkq#;2gAw?M5(-_-lZV@sY*CWuYh+Na+ubj~=QKtUNC`+4%jUWzkeA_Q0H1#(^ zU1NR`L+YPtDmuSl&v5~j*;lf-)AuS=DPxZa(mgU2|0oolo+&$;-upsOuFecEI7 z^4ZQ->HM039S6iE*ChJPhg$EZefY)2zYN4JGwZjB$`Wo}VX8D;;$SbQcM3%{@Y}RK zO@5WW=gD_C@_oi-s->ud)FMv|z0AC{0p`n~|A)0c=K{w_&CKRGwU^r@3^Pq^*6PIZ z%m$IEPB$~H@keHpM|Vqe?!SH|YZZ_<>1vR&Wz`=p6dg)}Ck1x_C#h0F2kDPyMoo6; zOw->$rLazwTHqK?%MGNb`DlW10*~dAuu1TgT5y3ROoVRe9RCkTKSGZ-lp^$mv!Z>0 zYz?pajR&r?2gzqiIun6d15A+)xDCi*TIf(<{Yxrpq2EbvTAVRBVuh}Y4}>REiRsA< zp9mFneqFrsUSUlJPMw$dQ9TRpV*~Z0#$MxmRRmEMlp^L`v6I-8YVTkbxWHk^|9~Yk zBQu>MW%Tj^J+SadxMrH3PJM=Yd7qx0mRe}Z%}rlh_TcTzu6^O(bnOkl#%*_s2Gv;4 z4LI583tG{+4gLo}h8UJa5sxSWkr+LI*gEp{Y2OHP!}RmxQE!dArggAom}=f6ghGNd zwNrn{gNZb?^Ql8BHUsm?Me~4!TduyupK@Xk(vXCb&dfv6@NsT=F*+mqKHWMdpgxhP zPvlOgcjS^>Sh=NCYF+Tkk1W|~^yI5Fd3t3B)u94sNUjDapnlOZq_2;*=))`l7{RUj zP<@ak;V}z5w#!l=9C<>emJ)rGSwZB35(u^{Sha#b-J4MQpAHK4WCVtklw$dE}%1=_@t3S ze-@TDuK_~V(&N24G5j=rM3OyZqj)!odJwB>@Np`0l5BMFUELD4s8&*yQ|os>R&GD? zyAQOBGGK}`Q6C6C7%|Y}O%C4K-DbJOpLOM-Y#qu?#;5v-hz-nIS52ZN?3a3~o03+} z=z0xt)^h@6m4mZj-TE%HM(gJaz9A+^zd*wwkYF`g=g(j)p`>!Kap}Zd>R$Jlfrj zaZtFfCrd~W&K`6u4&s`iPkexsJ~TZS>zK+Hhhz>xpHe>E6Rpd|TYFE}idpfdbmQk# zhVkNht;i&T2X6?cfn4}OY_$HFAVCZO8WoMGY$(&zOV3Tupe$PE=>KJz#{W-czSo=mGP z0n)J~=9G#43QLFqLH>-*#$@%|;7>b-ejC^ON?-k5kgbh#w?TsS%DLAohxHl+-$c)P z1@7tpWyKDMHHK%!K8SAJKTiLB#YPBp#omS9_t*qa{}rSBHMqtOmzwbSsH{<$uj=l? zOEI1s%x%TYRC4U1*@N3iI-(VFMKJ;U!*6dHZ#?VRMiecK7kxvPjh;QK+|<+A+=KqhRVum30&TLAdit`p}XkHrI zuLe1r(5JE32X5}F`GwzMM}%-60L{zHzYUZ=#qUu1%2?3>5j^&5_)zQfS;VRk!CUZ+ zsv?!3P*xV!S#~0)!{*;d5f9{7$)Xw*=c%>AkQ-MQ*KVoB?)htW*~-V24XR(B=v}po|2uB z^#P~0B=cTNJ~N>dEp7iSF<|Fq!DotPKMHt~%vpDb}WamOju;XNf*$&wx~if%uPBHPawM20p? z$9M_ZjkIeVuqu$AKw66Ll=cn6=TMwE&){4-I7tFGFOP1ulGTO2UOjNj^Cl@U!KJ7L ziTj&r1p1If0)JKSWt_;NhXeGSr1Dyz@&glO-kbGT^Ni5|voV!fM_xOr&$(F&o9fYOqh*o!!iFG4CpdIu>T>2V}Vha~KDMDLm}#H^by1Wx|ZOMX#}S+vGQeY7c^XyQr3 zd_m=#Z2TUWqx2coxXWHQE?Oe*~Sh7&k-i*SFdz~O$*3nUUHsCQf9FnaX)3fS?r znk*JY#v**D-2Ush(`IV7*v3l8LNzc~(SKn`{~81SHJ%|H68dx65O!te%B$xiU!dfj^PhwsKUb~rBx$pb*NZBIXBep|^B+xEm+h$mlaTc=?GDAqe zCLi~19uxn(>E)(L@p99j;g^EGpPFxk{#6O+^o!x_V(7^jSo``?dqPMa>}G$Q=sp7$ zvHS|f5ct|I7Mc0>wqHWGTfHSDBBBs>r{GNsOoQ3f%v5mBvmqt(l=HZ0!ToYDBA#+o zgHTSKyBx&dO&LPR%3TglvEEFA{0c20h8+`b=Ks~!9=gNoEuD;28(&CgXxCI3(_R z9H39Ze{fIZ?`wAmwl9o#sr#?d0^EQo%1I1xsMrM5gunL~Y|{{@7W078qqCzWWEqk# z=7NWR{hn{Rr{^e^?)QAN8yB>KZOvR?jp$2U3)&z*REkJCbZ$7a=}z{Fo?0L-HT|4H z&z5G2caG6~({QEl`^WC@r3ShOjfBOyD<-Y+hfG95j-;Lu65BZ^iJ5E`jT&Y0Zi+0T zQM(6~n-f_L;wP=fj0C=3=@*&x zeLd{V?cZZl%cA;rSekPa_U+M_L2=mi#)Kc{S0l$uri1QXw?Eo7^f#7j$d9h^ouY1mf8+JgdaBB>sl^6ZhLgaEGo# zanUQF!6luAhng)PWo?6u0Ff;8^I%7^%knGV3-nVwmq2VU0qw&K-;+O{_~p9~^D)19 z*#p5@_`KSMX4Pu;b?gjP zK)o4U?Zm!Omn*IWs#|3Wa5d{VQb{6ZmGSJad`=IwAcp;AX&e09{!*HQ8WZ4g?&7GY z3s<@-my9ZKOD<4vwLA%t0^NHIyy{9ReN1sI&)7oO6m*#@bo~()}!Z?L2z$r&cxhD<9*ZmdnDp0(_b?X!sSe7ej-M_hC z_YeE(uAsEkCx%7+tIhld#0>CoeN^rfU*u<3DQHigGX!QXWX)JNbMhxPzlU|3j^tj) z;3NKpq=2kp?j!P(*~~L7trp%msXZB>}NaaPJL#pUX+eO^zXNl|m*SkNDVe zh<9)s7+ND4ayV8(#vt-bC`L+wk&>H+xJPPgr}mI%tbTiFtbW5-P3=rQ^kB4F`$p^6 z#&*j#E(d4;fjD6)72UdV9M(@ORy5bePZi)JI+`bl zWrRp<8y#wWl0}sbG>qGYWBTJ-#KA6?MtpBSuoL4@(%E_-xHUi!C5(oiqV)iBm`s2D z<-mYe8p{Xr_ultgkLG^Q|K0hIR#h%t_mFQ%Wz7qKeDERncx?>E{fucEX2D%^DxRO$ zYqvyZhq8uNx_aiaJzNGW*$C{lTqf$_RTR(4HvYG8-WQEb11z&C0t0P6kB3D>V)iQ!qFwgx=?O%ZA5b-_I49+5>&=0?uv04cTjuR z?97{#FG?D!pAQ6yp9SSe-~~*eGJ#;=n_fulr?7X*yzbuqyC+)8XjsPI<^R&7GEOTB zur&;TO%~9b8q;3Uc__*kK!=o9do+H6flAnlmrzb1#Eou4Y}3o~!vX^_c4Nx5BCD{l z+wE^j?eks9h$>P6>8!dIdu7TJO~*w;2B?1nf8w47Jn|mk3^X8qyl+HS=&BsXDT-Ub z{>WCbDS5sTBByNJe4V8E8C`7NjtRhG2PB!FZ+IpngdSEoIo8U+hUzCo=B`;N{jNp6eP#f(=>NJDc#JP zEMcq@b6sPTmet{0;jPR-JeSalQ$k?%c|mhLCGV0ju3~s#9X^%KaqJ0rMO3k?vICl5 z(#hM!k}%^-9K~#Yp)@P>P2^c__)$>K_OVJB<=D5i#pi-p_!Z6Dz{cygrnQ_a&Li;& zKN8jDR(?h*kmv6RujnqcDI*VSU$PVNh|4&0Y#}N9;O?V@KM7*PY(JB@jI$kRsnY|4=Y)R)&2aEC$&j6C9eXY7s4R{5})qrNV+bZ#< zGU8wP^Wa@c%xBn5!ZANX?Phhk3nqE_m~FTrILv9&cv%y4GD*Z`rBVRk>SWk0-0`$xha-%wxvl zlm;BEDucLPE~o7yDrYYIzait^X_ZUF6{5&+v~h$mEmX*!3X~D0>MUQ@>i~TswxrU_ zkY23T*Jz;;#4Z(H`j!3+WDNVo-wM8jG@oH(xzx1du;|;*Z3jx|Ksw&u%JJW%O@mFL z81|(L1mDnXeJI;@r8qwaqqN&l&YD`^PoLGP3dc!KoTD!Ss%K!2IIMVyt82_5i9L|H z$R86J_0-MH3Axtt1pIUMD(4gf95ClsBo|8#Rr(2Kl5XH!dWHiAM1*54Z*Mfc`@XEgA|)*txW&JSZeyv8EzIhnZb%#o0Jkg;A_A|XE@{hAF~hYI*x@a3o;!H~81 zY=y7J>@euqheObY&&f#t!u18DFkElK=Po4SNCft}Fzzekqd2jE%au;xinz1wA~x&NoK0*AY8C23So;5X<~5|5rp+?=%bbUTCodQFHn|$bRPk>4dM#(-KmFG?>;c z6m>)Lio*$cx~AiN=}=&PDmZwuVvX8LXLVlB`Jw}KBPP$hMXRx$0OB9yDus04j#hu9 zJ#ITzS{GVHYCtWIlpb-sW)s^3y*1w6R-!zMxYd+v$S@)5`Wk9S+-@L|r?QW?Ns`L5 z$(Si7s@a45%a=q#A~Xg5Kw}PTV;U(EIO+H|toXugHRMaOo-AjQm?O+RGK-nZ3}eE< z5xTwdt>y47_*5i~nP{%?@-^$>_4$#uY$1(I@@Nyy?L9;?X5w!&sn93wz5janBoyV2 zU-Wuv$B=+8I>h2>ns+P}UTqKMGPp07pUw}6ztXrDCm-T2^FJu_hRIW&Qit+`!(x9%?_I_ zmeTuo(#29lWUTNi>3rqT?|W!hUk)yu-K6oYO@BcdC7pQ>J+txtGtV6Q2&aLk4*lhR zzIxi@=g29H@zl=0fm$jof4=|TLe#LNGy4!N zE$N}sO1hptz{pQDic=PQ2H{WZO zJT#X#wZ0XODD+_xvhihL1tNX;H=K!(I{pgGV5B8T1-Re!5`6NJRwHF1rFIMxf6*Zo zD_ftfTM$3A>GyNGr0e~@67QUQx|NB>Y$PAHPJu9uCI@~Py-#s3Xf z1&Hlopm^RS0#OR}Ujn6PZszQMIn46@Q^H$@)qQf9G`Fl8`Kw39N13POt3i3Z9YuPZ z@n3f0bGqSGPIl$#=6&#s3DeQN>`zx0QLYO+ltK`PbzCXpQuJr}jXfz`d~H(JPce{H`7S3&uiilW9L@Gda#eVlASR(E^c3dN0bo&wL zKP3LE@mzE|xG0fZvZIX5Vh~q4kPBG>3P$|xQt}QgNQ}JxHjQ&T8zrrDNy64#rad|W zJ=)N<_|P%SfGl7+qYqK5Z5I$1dQv_t8GudnQx9b5;0=}^dd@Nt?Y_t_cXBu#YK3I9?A@h`^41>%of-7$qiSaFKb-PIN0lSO+&kfsv)UJfcw2ozntxMy&i=c_3 zIuPo!_Me-|bpf5E#K+WgQ?wn)i1ay<8R-`!=#+r(fJnm4k_YA4KE=w9T%{D0^KPffrw2OR5tj6}8fq6t!p=1X~STisW_j*BEy~`;Y zGLWSlc(lW(L*xt?xES6MsP}LZXERSv8*jRhIXIjF{v+d*M$B3HX4DsYr5+uO7|%b6a#RGKL6Q(}M5EVe1|vuM;E;k zF=LmKjqhk>4r%X;jicEyZoIJ14P@(=c9r*+cA^M(C>$Ro{t9NoZq0V5;)OXn zX1y=F-RWO6k)0l#XO)xL#(yJbj~;VvIyg1N#V~}kOd_-X?`csD|FrshF`FN8NO{To zQHYSntS6)XVkVonJ7p4P(>UF3&Bspv*J%WYWmYd4YcyK@$uc{UK`#uyv~>n%+zU8Y ziM^s4wxe#$xHb(=QmLP|eqvY2_Gk$5B@S6v;xx2Wrot83lsIjhlacu9knfs*qjuR= z88gvXZS|LB1GxhcmSPv0nQ?{4RfJr(p*&{X4VtUw&DQB@Q#0|5%77tYuRy z{q+}(Q?uJF{kJoki%JpO0IT1J|HWP1j&mT~XHK*VHz8b0Vq z++yemk!WN@CA&rcqdqtrk(3Aa(TV9yJdI5r*CdIZD}<|ndJrjzlqUhbMiW`Yq+C9H zFFv%9Jn}ej*<{VxMa-iwhqz+HO#^F|ve88wphsnV<8()~_VdYMr`t#_G<7tNllHWr zETk5m)Z&2JjQOeqS=^)6V-=@ijYof5%3ik=hQ+d<@hQ%^EO8E5=B2xA(Q@)5dyNdo zOcJwNeRi#>O{6S?l{-#K4T$%gxLNOA#7qp*%jfQ^?vpXzIloc8z*mZ)wRt%Bgd{&+tUn7G@yM`OW`Zh-ePh|H4TOomsfCOaH z%|dQeh)P$e4={bot=9f#Rs&W0grEmbF(cWgwU{MYk*IZl1lynZJ3T`EWYo9oCLzAC zdre0EIYtT49=&Y;6q1eD)y7t8r!*`IU7{aeNX}6^*Sq1i8!xOJBQIaBVX433YP#4PEt{ov6kDey@^w#mu)%f35$T# zx3t$$Pt`;9{0Q~DG6=ZONJ~*yQQkSkTC3E;L*E_+Y0<|bNN1AD^t7LBuoaisKbE5R zA1$v&|0|urUk8R~Z|5}DYlZskJ=&3wI!B8)YyC{Byw`H~0Kx4a+UeO6*uzG7oor)X zdPFa-w$=XwGTx0i@2c`n^WBif3^zsGFBMOU_|PzdzRj3HhjfDE~xUD zE!Qm4tS2HK#2Nkx=l{v~#AFKE-Z>Du1$-($g@+n!)FqLUC^LFubvCo4QcLI2|Ll?S z+-XLS{rrnA4@ctS4}IpDRdl>kYKE|JeRIn1p&9iE#%h1t!*l93=9J8~+0{R%TK~tK z`r0YfSEHURa6*o@6U3h^#E6tt2NqxXA3MYFarN zwfAq1%#N=C7N8%K0^fX-dVECgt;1(6BD+DSh-4-+lW0j#2vM_d@OeF~5JlAEZyolO zLoK0z|1tJ-gF3oQzyGS|u6jIl{@MM{czB#2XYQ#M9a^QkB%IVBj;M}xVAWDzU?fQ*?YETrEhW`&M-+BsBQwbe|hPDfcWRg4=8?u zJ8?%duoP&?UmvDt08Oc63K@NY`u@v7yX1lG45a^g<(^dx|L8Sz9gm7YG-vn@t8jL3 z^*ZxIijhk|V7nO4j(cra=FUEz!1f+DiVcjFc+5J zD=uIe5i2YkH>JG&+6$ui?bd5AF!mA5toH1Iv)W4;#tvzS&5Jo;W&A|D>0j`AzV2^( zjxIaZHhl5K=QMYMOR1lzw|#_kNPDa_xnU+7WTSaJJ49m}T2A8RS2qyogsiWTx*Tx- zHyj0Z`EfeOvReCy0g9`La^C)$=x9M>g9JzdbvfVjpSIQIzcdql0kniO+vU)loL;|5 zw{m&Kcn2&?8rdPxI{79n5R{>g=Qa>;_+}XS2{#h0|7T z;BI@W{B!WQh@`X$&PGVEyfpj{$AiMY-fFme+nwYiuAR$(^n>8$#w` zHTw1*EpQafV^f1xE#D9#LwxK{ta9n9=Wg(>dyazIg7Ug_aE zbS;Fm4*0U-D#HwZG z?tQg8pRS@w`gHEx!gcWGB^AlpgAk=}W%je+tCyCq%%vmG{{E2suy1# z-0(Qd;A&+7fuG#Da!H)#PUGs8oG8U>f(YZlM66tr$)+rG<_|9(0^7IXhEvekkmyx8 ziNiMnRfCCq53$5O=%>KfeNAQ;$u+FVRw^8Yx6E7aC#WTl=LtmETjM>!`TR(mm+XL5 z<|o=aX$cc?Og|}4H1?Pqmx3uzDOiS4Y%VX(qj9mmSd)@BtE=~AAoIUmpMOb++SUc# z(_)n2;-}q{3XIRbpm}Nh<+}Wpc^?Kk^H;i8`*AUeJMAu$B6L)hr{puyGU)qBB=k+& zs@S?EbJ_E0(#zkb1^?)dzjY_6OvAorW2A`tevcwJsbdfYAXc@>T($QQ-=XrDKXUI!zUfj<3YHYuhCKptuDX+d1CU0)`laNJz4525e$~4(kCMBq7 zJP^p#v3E_QSt{*Nm?>4HSTbnGTklJ@^oj=a#`Yz*4*O`nxPHE(5_NqLVmD^4^)M`0;EtV}R zklPeJ&ySX~E0*25!m?^L?M+7>Eq#!2I9AL1YGe0O-9VFI_aro3!G#arXoYo^i@)G7r?r}QS$*WE5cNjO*5=c@p9AS3 zptwpVyGTY!t`2-f#m3?8I}X^yKyp{NKRNF^KF9g5>*D{hr%mnrX#ZGN1sx;&jU2^) zp>2p??aZfpUP$q`EluFG={`XtEi7z!QtJafp@kpsDh5US;~w+;K)Q!eiO}W!wFOUv z_AW~mBFKg7N$z(-Tucn8$ygDPBf6JO!!JWjjsj3&t!UCbAws37r8uha7)aK1+#U3@ zpa;5z9=av!nRAubxqcSrLyjVsuPmVZ(5r|)O_8S^&;B61r22zuK-V~;@o@Bno`lEhr~RvHw=~Z@@$lO6&7Cg}$b(zH&5wRene?qayLe%WxXDWwjHZ z;~n-gKldKAaJA3ytt_y;eD<=;c*=Fr{aDg4Hw00TZP&^w9NTPP+ee5IUBk8sb-!MI z6tQ^~z`t3`+(6t+=kiPFhn-f1*tu+_rLG{vJ^H5)Tx}T_Q_>Z6kkS~xX;V8#9Q0T$ z>@g&<$@#EO_-?;_BG4NsW4 zMCr#=zWqQ?%cNY-F87InnS^~$v>>Fk){#FDYY_2fM=7p;eVAId!AG^5&did|2?yy4 zT!_{DouLVP-^BZS-xK9@jnci3K9SH`oKGcJBp&NBx`co1z_C0M&5S*^1o%XX@hxKT z5iY*EZY6w|r}E+hpJA;omKQGxXz|RS)H3CiUt8(!m9p%3hr_@`FSn6t&{xXno>Z(~ zwWQ&C?ee1q7JdUH#=9FF%Nx3m>~ryN)g@9}%E`(3<=VP@$OCcSrF_nDTb&^#PaO@^ z6kl<(51XAfvruC40oG<<(ZrZ8Q*Hh_JhR6TRKz3(6($!v-lC4I0TqNXswHHIM%;@-xFN?m&ZK)NIm9{9aw0oxvLof-S2^Fe!Y`Y@siHa z17R(+Ws{c8xeWYLNDjkFiwoQ>Or@>+Fm#1JUN=-%yhMBbJ#7g;djGu8;w8JlPiC^x z3Cki!T^CO(YNc2*ST}0&E~2T;7bVekQ!cjfGwv;E?XTt1`?aKFvZRIXML$uiI_Q-? z-(QRfvKrgJ3_0w<>$E=dt8{;y%0IKef95{9pNU>{ox~E`&@vf3oHnzfy-f6^CB->@ zu*<90AIrh0XjfuSr=ypWKXmx{LbN2Mc$qq~vXDd;FG;zcT(Ath<2{4(`NyEyE-s*G zUKo>bA6;U2@v=RI;#%jk#d#~Zr*!Mk*2?`)1$PBgS^eAB9nZt3YR|+aD2u7hnQL4Y zFE`5~-TkCRjIo@R`g;B67Tk$IEmGZgmaNcI&-Kf7wf0b8XqpUP+e2YPO_6B(Y-K-c0e`vem}9MjT1_u8ZwMiAzE_EL z4MQR&$>2!inIuRf$E*Y&S*h*1>?~OMTvZ5(_qpnCUE@z8u(zkcW*xk$v!E(u3w>gl zi;t?KT(65))n&7i>-1Dq@8;u-oaa>Z;7oK?nsf0p@Pg2U)E1*x(+O+^!h88|aki;{ zKBV~1*9owejcoCf?p7eo!cYEyrGIUR?yn6OpIA2vJ4!FV$_0O;T5!qDm5!Zm4w=qD zndw8v!QRgt@AP)2?QZB~zX1n*A+4c{+Y1_-0q!7K28&}lkLR%mNNUgxK3{miLDTyO zLMZpF7by3P@8Zq6IYO+G#J+B>40+8$sk~3i+wOJ@L_1b+bWeSXEh1TUH zMrIX?EFaxkQS4fYM3p;2&u?!VAcd5>ZkO@%XZ^jLVWgM{rI#H z6|5=Z{I1p&FjfO0;gS>}w#PGx(=euv<#R*UW5g&8cP!g-o$g;K7x+@agA|cRms|LM z^`O1W9nU2jQDWbDApqz%%dvjth(C?};qLARNhGDkM+;!h)L}H>bb?j+wDVX2yuOUx z%hN-J=d?n&+PR#@_;W53yK|yg*WU3ZUDkuCuW$?5^ul!pgDs#`I>E*J_06^E?(?^cA5$lbSkJ!O67Mc!GRhcz6#AcS zNTe0InRF3!Pzr{el*4xwNe0ZvXOKothkjIySh|-8*(ky_0~|x7UL;RmL;FhTJx2MZ zUfv&hlcN?s)OD=j2@8XG^A_0O*5%U?lY>jz;egB*+|bfJ^v>*1f$~G}{90V=dH?o3 zN*57V^w`{xY?kgOFrRks;ZKFob-TGPIWI9hC4U1h$w+p-T-$cByf$D%xLkX-08=h6Asp@i=$mC_k zOG+ud={wI(?NsimEqK@QiF=*WQ>`BdxjwKy-rtS8cj+BEv-V@n?uXxvi(hw?@+VU} zHy)(FQ_h6`z7K1LM8AI(`>&X`X@tYE{8C%ci8(k$Qm&68bZF35XZV+$$?gcm7Z29u z*Xf;z_N%Uq!u-1z5t$KnfBsE(MBv`vBOciOT;(5gsBmxC?_%*@<&zv2c&TGJ?*HR= z@prHCk6=U&2dl#+6E+P$%Rk=c;yV$;L(_3+?9hy%_e&Y<7>s)d#}3XIeE*)p;m^Qk zhQQXR7dV?PI)k9M#PwiY-$dGh>l;WHaJ?3v3HUsSv=rCx;ByPoY+NtH=QPOfh<%*w zLoIwp8pgB1=U{`Jk`Nzd8XZ5<6p??-i1P#x3IZAj=2AZ4bl_YeL8%nt6XqD3fj{{D zy&P_z_Il&BysF$9<1&3=eRH0vjR{|?^)bx}P1Oe!-nNA2Z4_cvt(I(j#;AU^1ksqE zJ-=FZW*55s9)_?}XH11&{T1E2f?u^4urB@Jl@5;xIAHQqZMPa)=?n$Y=~Y$orD z4urEK_WD=Gu%ja-8=!NnNQm%zA5xJ=(v2ve#hq`HyK8gI62rRqMXnnb_u0~2^0N+FZX|colEsDP`MkH=l2jDV z!g^noj5s2a3i56*|Mk7^Ef@GMVLoKPI*j6fdc=^g1Es)=MU((T-oGJPn9L46KeBl= z5D9bhS3*H@zevmf#+tncNg_IUr7 zH+T1Pn7h+^enHKGg`*g+SCK;d>ecKJ)5Ykv6&b>QKI8MuS9GIpiPpVay#x420q$9x zS1eh74&EPA%0u9PSb2-A1CCL-xboB6>FWY-SFGH}Q7N&Pjbs_@v1Qe_PeXdV|GxBi z?A5*02XX|}|F2y*RtQl4B-PlHVg0?WOwh#_Lw+Elb5LWGlzPrE8KvUQ{v$}7#uijY zMmIM6nI(5-l+v@xywWC_#!l|b6Xv=3VtQ7&+Z=dXxff9o+;W6dcLKaK*r&WnWx&4K zY%uFpsf@JnRrmbtQ^hiNlUCaF1?X5H`yGGtwv0s^;-+`mUOIJ0F-N*SpncG^!3~L# zYIwjrvR-Rh_t7^7ku{n~NV^)b8yqZ%BquIOM^lN8uOh z^`09wUhZd)^+N39h>6(02Hz`n%WyQdXG&>{XDh&!0>KaaxI$qUE56W)xBS!U?WM4b z6vuQF{T8QDh33wyr3xzZkjXB@=c?gRNO@Uu=ajqso<1unjV(?`&#WswjlcU!sb$=j zQhKIQqgVED^aL?1u~G|JJbZZQ{h-45;?0n}#OKo7{+r}w$Nm0Y>3&1DCAg5*iQEZA z?Ss9<7bS?;+sn^$c=8|6m;V!e`AZSag_a8$RQRZHTBEeSUnark+P&X9;~`^-z8H)1 zX@rT^W5m_D?AM3sZ;jnS&El%C5p!#()_^?1Jkoy(V%@n=O#$`W0LF+T-mN7V0o%%B zh9UP?MnK=n(Ach(4ymrcDOv{|E25w$!(QwwaNCUy!`KT~J!d`U5yUs|{?5`b-~9&b zq6}+-(zekKLcZd~WXBoki>iJK>#q-qgPbwa%f^UFd@U@WXihYr;_i5ys7vl1xPO)w z4E?9ePb_q%5JWR$A~BmDl~#TrWU1BhUS>agmN*C&NX#g8oWta`-V3qsTvO?s+G&-E zVX4ec?QA-@2_R!bfj~pYL38J(K}M~*1txU6Jr(wSn;N#;AN7|vZMSEW(O*~*Mn6ehE8x9-T?(MOFQ^m%Nlr)Tf?{H$L7_EFD_nbhr7MJ=|f zLZ+n!v%4F#u*4V3dwH3IwyT7{bWq#J(Owixt-;`dOAoGUeeDnQ=Q&}w`}3^u*H#ZF z{k5>PRpy@ECxz9pG5iz=J^N7#jqF9sp|pnPliBJyml=hlt#jQ{Ka9UHw$;Pm?h+2* zt|!Mr;ZLm|F11S7(YnK)jqw=TxWoP@_h>w7@#OQiKyw{|vawhCM_N4jl)3K?##?G; zu2+#6aT7&bwEKYsN=Gut;uTxMryQEm?(a)?!Kt0&5u1P!r#FD!ejjv!?jlKUd!NWQfri0t|Ms8nQ(7v++S! zWL3$qufKd)R=KfdAD7Jf6jro&q#^eX9^w^FN{NPUXzi?x||S4?Ig&F%86*_!}XT=@+lW%yi-l!uhTdFQ=zoitEBCC1IC zX!`gR>G^=>;NiQpln?QDb0L)Xpqxu=UZvJ2x(Bev2hBIe^C9= zt)Su_U2ukX#R^?;I>lKhTnPO72+?zI-;xw7_Cr&w3*LV`PhP>XqK%3u8L&g9_sFX9 zYrVl^JiuoO>7!dx^KkGObl2bI`pt44`}zZZ;_*9TGW#lV(D8ws0``icxO9A_>;j6HRSwJG<8|p?>H<^JaV>7bLTu1%85D!Z%6|q{7Eb zV*A!L7m-3@*y`yL_xBc{Yq>qF#(k3}0_XZI-|8CLhyD`Gjq0oIa7fcfQ||J034FZH z@Ey)F)?jR7Pgx`f5O*2*e&ot~DBoJ-`=c4sqj8teI+OEshiB~c_(Z$_F2yK?U8V?_ zZjz}vMpwL}X=u3GEoY(c(AjC8tzw1x1X$3DIc17h{H!L4nu(;*-w2|Es}7T>J0yavl^Zq zU%6X&-ExXw(eocmX!r*f1;%R%d@=)(df9AwEO zYY`W{mJJh_StMbsiTeI_!beGh_&5X2h|4;n)>uU)-0>vtt{Jf=#5G#!RalpJKL_bV z7~5*0xWCuTR2~>=W>jD77-!e215!C^oaggj5gDr+Wpw|s+9Y*w0^^B{S355SKR)7 zz7Mse%|w4OyMO60d1{&tqzly4@O58J=@Y;7wWbrkZHM9K>WlOICT^P%r^sjpW{2*{ zaqu3A;=biy?j;G`=4wtd{>a^uk`8nIjY7@0d_H_BWq8j4UszX+aAZ=WgpEoczzzi+ z{qM7GqbPZOdFHA0j==>Gh9c=q^SiNS1^htKLX6rSPdI(F+f8OdEk zPQJbwvuC&SH~jsR^P)xOUIRm^E!KF?D)^P!VU0hBv5+8c={Km~L8OgHdvP!M2oo_9 z2$b+Qxj{ydSgCp14Wc55(nN6=)n*l}cXPNq#u329^yNOiYbc2`4bPN7jwMgghr*j* zKbM2HdiMXV-ac1o)Hg}EfH}{1>oMn>+;hGa^_}UYzXh_Vc!%Q~i^rNcG~83`o2c94 zzln(&^&E<{rB_TG@OQm|g!OzRG`G2UQ|)?KBT=b8Bwmw!&QV+i@TxdPDjFko*=Yen z{NzC09ka52ZZKjt+mx^Yi~gMr*cIN?eGvB1MMxWvC^lwHqDk1VdJ=xJe&;viZ*-$c z*sU4P?bi-7n}ljos#Ta5>67aRW`#uzydU-E3cs&gnH7$xH~q0uuJAj${b38{pE00M z!f}P)-0hb&BEm1j@BW>N?zgZ9yo$0nA+5yqU+_5zpB&O6T;D``0@vyI{17Smh!ob8 zE`EB}Sj%u_xg>6Z1cG4@5v?r_@zJW4B<_a!DlB(z@#pF93@zcTg<3-m!S3PW^IR8j zHx8EdxA@WBxK7-J9N>8tQ^f@~#30UXwfdy6TX_BZM*5xPRu|oz?8@El*Q9D2S{udnm zZOd~5jiATs!0Gh9ca{S94zQ4ms#+N6j^2si24(68y01g^9&1a)q_K(#TM_Y7A0%(zXW@46v zU8TFd@Codm6bF|5Jr1lnE=yw9i>wQS`)U!$r0V5*5>D%|QBZslq^FX6wK+UP3me!# zy(*plvV38Y?zv@Q8Hf(vd{WRiqvk4lf08?w69PGY0b`j59Q=VCqB7{qwLy)ZeVo?9 zQvlmC08~v#id0=r^ZkPlyul(S{NY9Zi2GHyQi-NP$sLmozmm#QBcg*%C`3`PcSMe)Qcm8~$rv#f-4Y%ws0W_21~B;m>I(_v@$s9T!_qD*I* z2zai5$K7r{A-;UrF`pUxuJ&%DH)aQV&4*%n1PN00PU{!=br|T5NGjef6 zV7w95f@34+$LT3Ir()y59g&6!nYJSn&|2T36V((uB-MS+Bni_@UT_};DqYOuCJpRe zncZjj$u~6-(A0)2b!YeqxF+FJyMdhH)qU5;aUFM)iHu(Wt2Uez9OjfF>*71c;vz<6 zU3}SCS0ut`ozYn&#%GoB5t~>XfHTFWqD4hbMWdfiSiE;}?&7hUaE(ISVQvh0u~w}k z%|taI)Bg|S;g3GD)r-_Boy{_-Xa^z?r%;*5m>pWDsWGG#vw9uQ*^AIubY365hOkUW z#4)kZG_32J*B)%uG!yVEri*YgUT%|;e_OAY1er*brsMq~WFt^u(|+T3_9*Qm2gn<; zRK%pwhTPZ2^y9CN1OlzCK8&s8BpW4rAvx~w9!z7MFynySw9k+I4e?_sZh3Q4QW!lS ziG~NdZQ>eDR<9o}Ty66jo1{OizdY8c-}ai&0{6|D7W{v3+O-QJ6=8){jhs^Gz{@m3@Q0oX47o7bKf8N#1eFKb3Rqi+ZcYW6V-|(j!C~j_C zW;{w!gWLQFb0-&4isA0rW8&X}R3PrMq^jTVbhudz&Jh@K4iP*|hntk0WMHV7VEmbQ zl_?*yw1d~X0yBs8)p~f}sth)d06*#H<^%`#oj8c9-J)>c@$S2G*W&SP>BsiEMaLih z{a4VQZ;*~5sgP)&ntq|{2UhZ|bU5(m-7*H?&nJ>t&q->qnYMf&dxsy~OCnFUiIYyY zNs}lKLZ9|L2@WGpawWMwhW(0vp{EtvBD(Ir;%omy8i1fPWL*sYMz5eK;i*3h^6~$N zxp$9?s#^cY*PgxS0*o+REN<#BqXyyyL<_|dhG7eghG`ePoYNql+K8t^S{)S28PGEA z6oM9lmZ_&SO+m9GqJd`Ky3Gh0Y8Sf5BvcLp?hT0Zd#@Ql&Zp1o_xrxSfBks97JIEd zd#}CLvu@9N*7Lld*T7M)&n&>1iI4jXCg9swBZI%CxB|~ub@=~7nNbTK z=1YVhaFlcv*J^}q5UBreAp*}Z2v&qFgm>`lMbP+N#AzNCeecsN4gGo0Jp1p_YdgZH z2$8wvv8&F(7b4vfpijr9dTNY!2#5qz0C1rx`$$` zJN|y4DgA0+PrFN@U4>UoPw1|uecQL|yDDz(X7>1?RlWme5OMxwy#$;R5|Iz=yJcNU zJ_%m+PFdLf*d@H7Y&zxEE69YTm4kN18c*ez4K-yyq%lF2a5Y+)2eqbEhq}U?cITvlBHwMoDbQGC~I;}wX67&TM z1$hi{dSBTWynxT~e-mgPG-MtD{nvbqt&dHu!TQDcY=veHLJ9Xn}f8An!$}EKH2U+15als=C^)_2DN23w@7IX7^_oU|{aR#t=%2n7(f2LRSymk}a0+*Kl=%1k z4vqTi&~)!Vz0VAk_2!X>npkrBdzL7E^vu1tkS;^NScmIVm|&!z3Fc>5cO#S__#({w zjwNFee*2asUm%zf5)rfrtJ5ui`rbK?Y6I>nhKeVVS zJL~)?no%A32k!snTj=jQ?e+ju2s}^+_RX(X#A`190Y0VwsV4gnQ|KVs z+ZFMG3%xe41ZO^#S3UiRyTXz+-xG2WXD3Yv-(O}4k8}s(V{qk6a>!dev%RWzF{C`C zb{(Esh4%DMS8Dyyi^$=%;8~bGVFL9{PS|#_rAM7kBE3!Sc_DA5ad$0KMp5wCzBN>4 zm%EYf?c!g6>9+*=QGOy7SLtvN4||`w`(_n}`tplXUNjD`hd0)!Nj7yW2ag{&Ttdx6 zAtE)9Cu0?DYGw?yF`)0SraA-gwa}C~{1GWeYp7xQttnDH^?Ce6IKwMi&p=B^FH!a+_7cwU* zr&Xh@AAtt>2#qNFG+c!r2r+&I3oqyLd*$N4mmZWWj&*e?YG=pid`m9M2kLb%9#d`3N29goGq=r}81$Meu zZ%DDgi~Xa}AKM7e&7trhwo%#@>+uKz z^(Dugl&}lbM|FUc^YgJ&k7CqQHL&kv>hbmLl*U?EwM@%INlA3A4fk{hp#yNsM#lVj zr!Ef^lxi0%A~Ysr=&VLm8TqqxXZ-OOZmx70oXBB zHUN$7#RIb8kO#2Xk?0-)_YI1v7$?)S2QgRN8E97&EIuQRw4Ax_xBkp^X0fh`ws&OF zCh2{KwzR(J3QBq1vI*X);A0mwSc90Mmg=e2WEU(=PKm5d<_i`x`kw5Br8wz^|6c-4 zew03AXU+n&T}R<2P;C?FKU;|wV7|I2i@FZnsHNy<#ChJ*AT_-UNu-&K&$m$-3-s2r zV|h*sjqlE*&-*pK+xhXc>vQHKCr6^RZ9oVv?%-Z(W}+&bKW+Sq;*+u?dUH$T{&4aPWa!0lx41LW-Dp z3Dn=h??R8t&xQA{Slet`BAkf*j?> zFQlf3#e6q#7Q>56fIU~R$P1^iUE-Hrz?O>)!k&;tdq6jT$tjefL0T0XS4I016Bmx( zP9c4ls{IsQ-SNbMa=r(ewaj7?odpESJe(zk3bHYY&RK;-_YFoG%%a?5cXdbc{*BW6 zpzi994M6N&IFasYXlf1a|2uYpa(d_L{khFka&_4I)ZL*i2x(`|q_mKmr zo)ZhQbE|3F&^Gb34@Iwf52vNwOQtN!ajeXpi}6XEpIJHhipII%h+ya&(391|@Dk#A zQ>I>#OW*Z3BHuu+^W)_O*2N|NZ@ zX1xf_bsGB|I%ls<>V#j44e(7;P}L>w?;0okr7GI(eJ$Ed?JhF0b6qY)qdc9UjT!mW z0HOW{{HXvt6{&5Tl?2_WbS{#XUdP0|zxVfMDdDwbZyvz0IQK z8E3>DO4mf^+t!F25=ETF)}I7=o_pTRBz%smtja%23meX7dm1DQb6)h98l*ag4`*!W zMIXe~vh$)+YBH@{N+mX#7>OG#X5pOJ>uS!4;a_n3+<4MP#!DDaD%m;sivryl^!(*z z2F7+yyzZjqy{wqs&>&SZ2IPBA`~lApS+YBR+4VKBjaItHEnNY37&wfPQ1dyg>nBrQ zw#QS{(8`yV-Vi%_=$W*}cFJ@!GZ1SOaXx0H{VLF02krEByt^LnPF)&mJ|f%@zv}_w zrM}*57fbnI>Vcg}E-C_u^t#ju9ugR#PxA_}sTJiJ_^?^@vEAhmk&W9I$`O`VzX&9rni z*=w2u`8G$Y>5eWnEp?!-E#0&)(YfihUyQ(Iv@T0dGYdv_w9 z(=MBymN;KLgqwc9DwRUP6U1{6JxZCkdX~|S( z+AfouCqw51#s$5TkW*X0q_jx`@0E4Oqlc~S-r1bm$ddPh;Kxcvh&~bWBk)P(SFvY7 zcnv&MFl@;CeKxK_x&u5F4z%1n);grkh!?|lVkEBTAsqP%@iJUPFA+B{M)|Ox5Z?z! zUGs7O6ymQVJ{$2$#8)Ez9O7FMe+u!B5MPJ*9D2WwkQWe7MEqq01AbeG@BzX@xUa&! zsfcS#{@{n{sqnVUNN65cVRnDtKMM2s_N<4XE#VSnJyeF3mv}?;IU0#MQPnLsWeF2; z4jhBk;4R3~^1ouqDbxYBw2+^1yx%O1Nr{~%33w6uXRVnbg2@n^XcK?D9bfHj(wbW^ zA5fd~KuDQc_fDPe(`}hl<~;msmJCOJ^t^00@&taY{zOilz&Q(#&@<1>(Xkn^&~;dC zv`N7ho0P{qA+g1Z9@U$Ng!$k!AB2qdA~*%eN5IML!py7n3$iCWwcyrv#kLEjh6$G| zDTnPHVIo4Jq|@|Zo~)3EHe5trbKqBDyW#srIvP}^WkN_!vS16f8iv>V7&9X(LYW@b zMxQJ?i)|3*o9QX2CUt#IzA;S@#n*3t=ZFPf$aRO>bnL%)?bTgArt^bz+OCK%be;MV zdJ(82?I%mo7Dvz~!*Pv7cn@(ku75?KazdhuoE2$W139nZ1)$?##NEh@M_XO(9hs&B z3LovioxnGaN9#=K0*XltiM;PBTUC~07e{mvte18%q)S$&smXpRu$ptr`ksQu`Oq|n zK;QkQ`=&gkA<(^dSfKdhqJQc);0unTUMmFm(@CN@;uwj(WS5meL&rvRNkB4b7mK>% z(LW}+;Hk9M_67D(sLO*KWOv>#rZ)LJj00N+~OO=|0KA1&uk_Y?{~ zZsyvYBIvZ`RN2sOY^xPkUR2+yMA{WmqR0fMRvA#q#+Wj-j!e=c&tr2I1hZMwF4%zO zcUj`L2f})H@`aPa{6nRNNta1b)8oOr2=9Kyar zhF>*I@jh|YADKF)Le?YyXJGmnNlmqhVs^r#YeiKi@AmJQaZWTJQ^l3>W2p|e4|rjp z`g&)MODuJ{e}6*~ExmW2O+VK0xu;zpMg8whk3Z~@T89Cr?;iBp`pj@)D^`_Lv3m{b z#s=vuuByx6lw-q`-VIUUwi)N>?#Sw21TwbOPJq4|e|%?-Pc^+NO-+Mz8?Ioz3&pqS z976liN%WPocF0ODxcf}4%t}xzPq2<-3!4*SF6>qhRpFvhBiThkC^Z@16 zC{w16$}^#n6X#VPnkB2aT5SXG@Tst~hUR|Dr7ZKK{j7+lZn%b{2gG8=xCau`m%75- zse6D`)Gq$BYa9GY#8n5SXGUa7GA+|XbaS(mWtu7`!X=)P==)#0h%N#ehV5cHv~L*R z^X7bvs>GY+6YpYXUKY>0%Flb|qP37!P`aoUt94;33%X;JP0HXOLtx!mh(u1CXY)7#V@O z9EPsSl21;Mzo~e)Gi5B=1`ugkKsIyX#HrlQEw@wO%54K+V7CZtmrLlav(=u14gZ_}dQ=9>B zlE6#DOEoH#orN>Hu_c5%H=vBJ2w}?#3d$-7B zAv}Q}D%SZBIN&_Sd3m8Y)PCky)}O? zs>&45H*@C;Z($s2j94+S_f3FD!}DUQTe`m+ym}r(bGp(<&rd)H%seD!3-FM>1$EX; z@^+G^DRsiIpP<&^;H`m>HH_|<@Arq5*qj`?)1fn3fRbzY*sb@kfYu{4QgO<31D@_Q z#3rWQIgImsAlp#iUvY(Q)Q@fCW1>O%RTDGkCFhj7S2XBOK##4-e=0`g-fr%}!-hY= z&F3*dRqp)wpTX4|eq<)EH7vf+S8MZ|?tMof8vvcqOL))6y$hRdeGNzjHHKf&uc09YSJ6Xt$9>O*0#Nl`s_=48U-1KZA)U&?%{in;GiX?JXN6>YKkisu{Nliq*!7QEWDduTSA((E8F z<5R2uJJ>!AWB1=#6+~X>F=TAe#>k8>!4$^4ZHgP zjgGzNHCqr+OI}JTIjl z%z4(mubD0tV!xCZOGYig`m+@F{1^{}nQRvqchURX4DI#HX`WioUTuxVvsc4!km^jw zKAwzXF`CxGR(srmfu7X`30QRdl}l18BxyHnZ({El!|RzvLM!yEK4EkG{VtVHf`?b8g4`sN-AC8hy zzcn*@3;M(N*9cCXDK60PX8Qi;?)T>_g8SY-i4!8OLSDS3c>-qDTkz#dpWf9&#@TJ> z9ECYa!Wj4cQr8g&IA&1cC;RBWUF0osoy$`SGXAK2TXO_jW?Mi+TEsxhyl~s|&TjiJ zjvpaQ3dc@_@<%tt8@-_>86TRa#_G5NX-97`-kuw9Z(8uc+fP7$;i7}Ae}p@=>IKjU-NnzG1wXH~VIeOX8Td0Ch>w~@jun>%Q3B-|4i^WRO=;v z=Gb}n<&z09Hs(HRxyh(xZ;_3`@L0uJAo(iwhs?MsR{lY!SaV08ujCUB$t%M7qN;D* zK4{_hq?SyWFWdtxOEPkr5M&I4-JKun9UW`axj9<4dJ?o+6mG7UYHc$2QLW7<&GP$b z50_V*a^S8Xjc>pCZ6dWT@Yoe}*=1wS*$uoEde}~NwW#Yo>1d?ie0Dzki=yNsgN$dP zZ9p~tw!@O*j6-Fb4)29t1MO6Vy;15(*1ZR8Li_xN_E-fP-;ZEKkPhFAvjNpa$k-x= zK+n$Ll*u4dj#y9?BBWJuBXOV6IFtRnZ6WixNmNexbak8%I%1+3=m!g><5R(fyTor@ z@PRtkaR~Gc*V7eRw=_bmz>?DK~7v_@PqX zwS9Hk49qgF_)C6TpZq^sI7prwp0EfqXxLq>wd@X#;H~`2{3dFRF%DXdXn8&Od&v1? z)5AOLi~8Du`V%AiSELCszZnabwDM=9m^vyWE?BaISHc4ASk^+m*Zed1lNF23T<5g1 zrlZ&|XVpVO4;c{clLla$`) zsk8^ua?taVxhRLSZIVxZHsngv9`4T*J=7qR*)x&jbC7^;gWQPj-hyn=!qg?@28}Hm zT1RN_5zNH+CF=}b_BRcqFPD%gK62PO@tGS5OQIn)3b#G$P_|8AD;%EwcDJ6n{FdM; z*&7ThTY%}>pmWB{VpUfpzgNt^aR!*}i8n(6?&|tqhJMBn$d(G1-90zE4E=vnYv>yf zBQbyebOtgV1Qp_^ag`7{5Dp^P5a^hBlQ-mUfp7IXNZ{c!bqsMvgZIMh>R-su5!NZL zNXLp(Ya#X4T#-)YrPj^~rjk?QykWsTf<3N=0DsLmpTYQI3gHi7DBXv$6$>)GN~v5Q zzJw}kV7Wi7_zAv^KZ$)7SK?ioc*~Goce9uM5+34}@cWk;;Z=S`;u0BfMsp{?9j-1QItG}N(|}4z^#78cjCo#&c9-VSzS0bH*HdrRt|JlN zuzGz`MmB2p{VZDV{2)yl$pYhgrIBi!{n-736gd*}n|38uVc+f^A(8LOjKHXW2;PQH z+o^A{LwvNLET{Gvt?OjvpSJt5<tTY(Pk=9j+#M^{sY{Xi3qF_X6$G#7w(7^}scIZD$h zs?fe|Kst2qiY#uM+zzh;UzxtpeU69>J@PF%*K3U61>LV>DD+7^}S0^E`PTl zNndGfaUA8j@+bN4(0ji_KPD4a!y5{%>A#@G%qTSAdSxYN#Tu8a{5(!P=uSXmy#l`C zytF23rcjPi^eTE0rQ+h?^U|>-&)E5ej-A=i_jnjuHZRdJ#BG+hGU{)!#>n2vhVH13 z@!NIaMVQy25&w?h#iRstExw$rRjK+`;_`6y839`w=D9?Pv3w?}D=(wIzu3Qpma*&| z55p*aqH(c_6uQK8yehIZO& zp%k6o(X^k^G{sHTrT<0M)0X9+Dk+Zc>y71I|7kA6>^VyJSxb6B8`8D3$U|x+EEjYPkvnWxIwiy z+Tu}nPk(BWwmWEvOZU^(-0A42S9G;@;0=4#xc{OR*A+o2gnXmnJHEfKK2kMmAlF*R zW1e^DAT#;V5rO}0jtFS?-Q~|4#rN(|Te*$R^#6Yx!}0%q$W(lfdwA|IFxS5ZevZml zZk>kg9rJt;0{a*eF`CO7wnf2 zym4>lNnkD^%t3l40*^o~7=2;21)c7uUxbBK^n`AKqN{;oR>oq*{PH%H7q;7B>vWvj zJK3&3%Xo!;EhbfyTFpn5l90p-=R!|GzG{wL1WN&9psY!oFgx7O27e!FW-0?q!MRfK z%y(Nk^;}6kb63iZ3w?G<+J1W_8)TL~W*a1yCi6O6&9TV$1lu|@JUb=i0y#`~X=iQ{ zU*sIOHO1$0sIV-h%U&)JL1sK}UXXKD<&%ZHdWimW^WYfOzcHs}rMop^GhoqVHJdh6 zuFsU95$omFh=rWdJXzQ*y_XaOjF(4j^GsCo7%tq$uR4TT9vZEgR&t*NYmQsO{f7=i z%X@jwA%kT1NIj?)@mTCj-;YSIkwyP*H@S5&p*f?&ywanLW7{;03ulPT13$nbLiX~5 ze3Co=5dxX;v^~j`gwv6g#)am16Fu$h*O*=mt9BpvOiOh;qN{>1OEEoMtV_&wF_U0d zw1=YZ{LOV(5`Mf0T4l66?6%M-HGF-6ZPTj9nI`bEHmz@gaRXLRm4$t?ULxBcw*sg&hKk^tC#oVyx-{rAA5YAV)U8LeY%$n-DjFt`ZAXvos zeepE!4XY8KHo4Da-tUYa_&o_`zpwWH>PO<>+3gsvexETFab{UXS<2~pPYZZ((bw_Y z(zcmitz2Q;mcDHkhk5h!%olO0q;zX=)w?BLe^@qR=Qb8nETY{?Ek)dNtc#XFAp~+* z?9na7rs7!z#^Ma7^hIN_37+~Ct0C7_p=@YhV2$JWj-@+A>irsi_hL-dK25X-1?Q|W z=q`i_Zkb6HdOakJ@Uui{nsLtUrPuX1y|$*f?crlqrZ4N$R#XmXVSi=u$hzQr!`HV* zrkShq?O|_Ym+gaHcHQEXA~z1=i;)D1eMqRFF|;ud@t%TBMwX zmjL+EbodNQ$Ep`xyU9>r@2*P)i&`gF1SKq> z&xp(6F)+rwxtc_#+nxt{=99h83y)PX;}o_io_UbUsm9(>!gC93zJa1OeO!F)^ifDV zH8E$z$8HOUw5E4{4=pG#erC4(P6~p}L|@w}rDgTY&P@-Ttv@tdRj83s524+&FQLwg4(ZlMA?mUo&!o1ES*NPN!Gtj!(M8|c3(LL77frYXC3V5X*m@9QWeYTSK zt-6HuY7hEj3csBX;>XpH@u}`T$w(XBN6?*~mm49I?)s`N%rsK2?BU)8UZzMzVA5Y5$XXh!gZ%&t3&G*>T zc(=;fEm_}7;o2+suhoVwqIDsWpW5X7=MI#X(k;fL=?J>TEF8WQIdX%(@|BI2B|L{z z%$3G!FJO+^X^>x_CBd$TUC4jp(C|zNaP)haGD1%}qhYnKp=|0~!GZpBoma+V)W-4X= zSr$l;Ds^wl_UIt5QK0L;TVDp;ZcOM2!9-b{tB+tmXTstct%)d7ad`k z%^8$ACc0YL6p~{F!dsXS=w5L}d;D=toO|_o=nzYTVTn6d7^DOq~(`=u*CESV7S%HjutS%j%3-m<4(x^=f zuGK?xW5i4rT=Ixi_~{Zt7v&p=rEgih(l{)w7_<5cBlN=z0kG2xO}AquU5V8spDFrX zQxG6rG2erocYyGzbR;6EFZNMHVEPA{pGsOCMQQLiO$IWC|3I4$mr}8BIfZs<`G6%Q zu$^3lU_qSPQJTRUK8mXmSLZRTdkEiR&HF2!pN8--0+oY>^OS2GTET2&ARRepkwvr6 zQciTPwYt8iXe2>fWC^m?A}^HpdF)`t)!RP@TBoLIDCWWtzRvlY<#HHZSAPzH zFD$}CLb`}`(IB{HBz5GM86|tQ=g7- z0zBL)*=O2_FEceQq@4e){v*u%S+Fd>Ti;hMJj`F_&s`^GMVW_#2LIPWDRa>gRDpd+ zC2b2P0n~>)>UHG29oExmwXurQr@mtML4b3{8#n*@z*qO&45*gIntCSz)B9{^=> zp7Dr77C+Ajx(&+nq8+lP?Gt$ha+t(+){3%os2BRqhR%EWh^AuHAQoSJvsaGNdvWj; z)n9h{CD5Ff+oP9Fd+;|FGg?NKY(#n2g+2;>_C^bR{{{G<_u}L|DyP+O(VYY4@rj-s z++}rZc9ZDSw%zc}GSB#_V`#-p%p>p9;9iU9((P9&KKHa_T!lOfb{J%M^fc& z!;WRIh3FI|O!>RPL(5+ct!iU@rgsJ%@NTurWF=m0oXo3aX!&_QoM)!0O2(+Uk`E5b zOTwD;I5+z4dQiYm;@NH%=kf}i48_tr`WXI4@%3I=1@%r+11$xdGtI)eYND)kddIK( znTiGQ3h|aDZp7n~x0Y@7_8QK!CI1G8hTb!&9tepX`uOeJ@^X3>3;wM~<_uNSmRbkw z*PLLiwbQWsLOW5v33I&YNa=5_0{ddnoZF%-{f~I{wz5KAUU87x%_EPtEqJ>%82#qI z-rh3k?I-P&{+w|EMg|wbHXQ};#!R^ow#C3TzG8nIx+}$oq6-T`P=ZO$`j`58#NGB< z-4S_UDz6zB5#IGO?D)_ITjme{QJeybP!IEI2PlnVLA{^E_AW+8rPhj)=?+hO{>M<} z_G%M$s6EWwD#xi8gL!M$HP8xe=IzCns?giGt6t^EVc1zQpq1$3%uhOG)1r)4lqlM` z4gaHzLz-#7jWS-lrYK!|E$^epe$$wMTDmHV|E%5nv47umO%8AIpPA8Oe_^=!M0+4R z)SPSvzIBHskfT?#%s#T3t-;BiHV>XruU3E5y{64O>KkAz4Q1bL^O2uG;JTq5Va~Yq zdmN;r%g@$w-SW=vxk9>k>pAT9+AATE6)-n{KWTMeo@*=tT{kL(#N{-mbieuS?I$+TPnv{6GdC1cPQ2pee%bH z6gvsXDL|M6f?(bc4&r)=tQNsZ3FGyj6_s-kBq!X2q_ZIqi;C@wu*@IX4`hr&=BU zZXI4_1TA5huszE@`)5bDsKqDF@o~Mvn)j>G7Sg z4ZTc$|M`CBF#TVTr$&$9gp8OIB@ z>=h(B+pZVh6ZAC{!#l&43^{jls$7?E{6=*37}9VC3GBy-ylgk)?1UE+tYK{Svqx&1 zgt1o=(jVxP==9qJJ^`CR=kc*_{%Y^+xcs??;xbknm5PhHnpH= z7_@y_X8#9mLiy4#b5F*`NN=Ore0)lbpVM^^; zGiRm00xf|QlOMk$lYuVEvpOkH)T}i!N>h;gwaOegobkad-L@~#%xM}?K9qyfr4kxI+2sjVz z=7VlZmEY#xIqy(c{S3QHqP5|7r&tVs-tFcc4ox~euLuzK&OQyD!5g6Dylz^iIOx06 z(d=o7!_a$jiZ9&mz*&L;bPYi0c!wn)BP>C97$F?@D6O|5PRA-VGFc|UJNkali1nU4 zBrs(1WbJ+9$WEa!CltGjokB4FzbgT-I;!mcJW2aOdk$e*r3ABX7t-P*!V?4wC-(>B-@G_nM$(lBy` z4S6xHsEY=5;rN#;{Zn&bg(EA`qyxz{nIgh}DQTJp*QMl+xtcBW)Q6r2^w);9EAUmK zZ9~g1?6RUhW_*jbqY>Bt^ZXb6ALKu_D+2kGzWjgL3K@O+!?&E-pJOFY5@HUoH2Ng2 zb<>T2Zb2qWF{)jB+jt=}5aT5PG9_TpOeFemai;c@KsNV^&C+(W9PL5ncGny}X>y%U zD)l1vjabx$aRp!9vnJxaez!0~H9*z^W$toPz9EblHIX^#MQYKb4{$RyJ~ zF_?zV-v4hJ9+h%X$6$Pm(vaXv4$F8S^f!NZ-pE(4abx!X&lWn-E1-pZ+&yk^3vuXg z?(-+D6K%9!8iM>ksqo~#16R*jV*&tV=j`on!U%A$$D{5sy#mdR%(?>OzkXE`$U(58 z&~?N!mqEIasO4M5dwMnQzT*v4QLy{{~k7Kc!t zdyuBzzSm9rg`hq4!Fx}dtmGb0A3OV|KexbR1K+M2`1T=uo6bCg`@!9BuX8nS@zCN6 zTq!Lcz_-g0&vUO|{*XM46vl@{&J(JV!xc6bYlH@Cgwl3ee7whdVD-p5UWb)pR!`)- z(_(thO-CKpg*9C11>R5&R79wcU67jfeIjCvtV}kx|PI3vr)d*&yF`|1NAablTM|4EbD1{a&4D{|jSj zQIk6AO`OS_p*ciRL5BhrbZAl$*79RgtFX;|MQ_&39InKwlN-=m!xtA$$*>FvJv!5s?R}UFSoAP{u&j#F)34l`eexUcIX*5)tXV%_KabMRd{E{ITA8Ic1G@Q6}nQ4UiI zkMXdmVRTqcOS1*&=t|}+swYWhTtSems(nAaxoQ?U5X$@ZaCa22?Jyr=M)|glV2>=K zdXUHo-iX;DJ;pdZP1JvDe?{{$?lGm$@a*0%L48>%m7X6eQtV|~*QlU5=#zY%t;247 zT2czzrlvV;#9JX2TyH?9pWB`t-jfZ?K(;2k2A=uyIb~a({FwR0ED|y8>5LA`;w@(I zWN)l`dNO|~HRD$Asx!A-tEx;CAD;3i4`r=flqmtR0`l$srXyJeMrsX}kPXekx+~BU zN>~g|Tpw+w8d)b`dy%jh`bRN`Y9Q&3t-yaNrl_WjpSpA+tgE0Lp;yNkVAb=PINSy6 zD-MXHIMeAU;vmJCvedu>w{`Cx@sn06*ER4l##nxjc%+r~IOvqbLSnrr8SS|qacZBP z=v-ZR5j8vt$@ZieWm_f(jT7^Hs`(SU1t_v818{1|_SD)7!39gQp$E8q(oS=n@ROND ze`Hg(&16*fgUYH07p=%%x%fr%f~FVTy7L}eja*nLoe{si!}3>PM@=FZ*bL!t8}&HNH*<< zv#kX=!9opevsv3pAQ$IJE0-QMRp-!gK%%H_Nxz3$I#<#D*I=z)LiMy07MrT>qJmKD zg@nb#`LPwAjk6mGhyMOv@5ZGMf%iZ)- zSdFkqqIi#c;JcLejRLvA0)cYTC7Q#9PBhR{r=y?uWY|Lor z!bWGOz@mtG3bRKcuATOyOK$SGgW0eSI={PO=etqkA(FS!{@hI3&#uR1gb*qK}m zym5Q)5u2_<^F=!c7A+>LS8JhKPc6aKlc-Mi2+)X`9{F~yymbv>CMB7-rnK9csdJ2P zhK)7Tx9As7H}2+pfli^`^bN{FYxg8-7h%*wy_Aw$nZf-^sAPc+9H2xoXC7SWi1)>yzitOhG^J z|DP>Ay~F#!a)IL6q`{|5=l<(JV|4*3Wp6W`{ib(VKl~7~HI-AB{Ko$Q{WFd5h)^Qz10Otf zX|y>zC)cbSn4#RWTg3D+e{Gz)gwcXlP2IV)rp(0d?9d!@`z!vmXM0y&7VPHB0#oIU zb5l<1pA(W5m=%)4RDEu~Vy?-Z3U3_#wPz%4({esxQB8K?wfv&(}+uy3OX}xrIU$zZoN*;j6PtghDsY zwaj)!_(D=^ui#tLJDxjm63^y2{(BZ&-LdUMx|)>qcKt$Y6bRkMNqw_os4%8#V&9xN zvp38U1Bufu#{}@FY1p+Dpe;Y^83(!?U806{Dbd{!kN1o*{h}L_HfErtH}&Z8*3S;erF2n!Ic@LJ;-uFvK$}KoO>~ENNz`-?H@%9{mx^yi;l0;; z`sY{1_L+DB_DcoEI!8mXho|!Df?e*ru)%!?^4aasZA5qm@pZUTeae>*FN5sw*xS&V zM7V|YDO^XxxcqIzmmz+XK96e)o@>B02x;(Mke8P66H>Ebx4sj$h8T5LI+OYG_wpf1 zrlDNP+rLw^H&Dy4EZ`4l*foejOZ1T5^eOnsGUfON{omuN<_lAJJuGqqjRwAKMuW5l zn!Js+zX%QRiak;oYy6Awp~`0CTGz@kt0WlU@gxS%?Sn1{{UXi1Tv=!Hb>~^3ym)bl zI~F2DRQZ6%Y!_GF{@mdWy&2KrWzy@s(!2*KnG0FSZpd)^bxSXyZXGLNH-u{;!fObW z$CQJk{HS0f}fAdYN|m^PmS+|tUE7u;qbZOj8(E^ zek$b9v!#*nDfyI(nbvW^qb&g)A{SFmVDIyjW3j-F{pIpKCg8xsp0z^h-$3zaGFmoy zj}gd7wpHc@JCMG5Gn2|@>`1xQ_=O`!p!&AneQ(j)s@%0@Z~x#>xNA#lKY0!3!)W9F z`rY0Jc_HdI?z)sbj4#UlPSRSG@V2o~pn49}4mZ4(6@CfkT2(=2L02Gi`pNPRW!x&8 zhBJv(GrMKC!<~#*gnebM792l#dE*)JAJWIsQ>zr_igPY1caQ65(ClpDjHsK7cZ9jbJP0ND+yX zs=soegb}bYPb6c{+UD}q+y=T~7N=GoHmNKLGmjcH&j&qbs*nQ4>BlId{D7dwH8H}o#y1RJ^>oMdie;7O5Gd9Tu#_;4D6awZBkaa# znOEA5Nxs?;BV=YVAx6(`7Ip$LSb24OaPB5U|7$ffBiXVR@t?32Rl3`f1s^cSwgCPJ z77B`1F6cdj=>pz;LDr<1xXEz(atUM^87;#DnFJ=fvvDpg7oo3=_>IfHPCwsI+7x~* zw)$7G-oX-#Yofg1Pc~LqZhXh^eLV+zGnFM7@x}|ZgshF0XL*YKLZDEQvaWU$|ApfX z183U`4+ZZ-i*dyP`V>c>(!8Fs`qr}tLWB)?ZY!Vb;P@R5TJzBZHOCo?9(9i)`p>S* z;z}Hc4FAUWxF*ln->IkHrd-e`_IC_r_D>v?Un^Ix?&#gGH2sX(G)#y#-*Wqdzhb98 zgv{$bvKBhW$6!y*2x}`X!ZoZ%c35{pemsXMS(HPH&Dc+$>C(ETk?4!b#e7cs2tEgr zlZ}`x(WX+Tt!9I z6}Q#qda6Ye8B#zwyaiMafiomOhPIq{6nqT;yXld%47YU8U+^n`gyOBs5}n1CVBVj$ zWliWcC0#@6p z2t$gzv0gfh>pF~zpBm%cvT3?L{~>m|Xx_i}G8lz(ZE>JqsYKk=^@S~A6KuBG&8XGp z7(RF#c`L=q$Yq;vij%sE9l;gUcGc@m?t^5fob@T)4$D^6M(?+n`-YSZX$$g#l`F4J zQ+?p!V^`o?Ke`nBzhUP}dDlMgM1|DeUly&fPvw*QtX&V|oD|k7Wt7wU>jBD1#PENJ z8(hBWJ2EwprLepJTEd6a%luk2+{*&EhUIVjP~Miy4md9n5mmFmFm<0GQ~K{D2n!~SWvjfIu$ z2MZw+@DdoeG!`>S7%90fj_tX7F2MAiH*t0ul{&Ywm3cG15HmohnfQhgG#QJl`!9+( zAF^6n7#_9$MjZk`Zue(tLYf(rW{^HHVbJ?}ygw*yMLKCvItgiJP?|yd#E3!f2jcxf zX)Dr6gVISzGlS9$(kJ`|z0czPL1`<}NrTexe%s0nN;52-+f!>34S6%Rw)Ds1Vd22l zX0-g4mk72iZw7kMP1<|tv-)nC)AKxuJPQv8BoWxQ_wehC=#i|76vLw0L2n>WLAJuEVRdgAVH?cI0t?SGFI z=98Jw!6C_dgkU4JEy5ZyW6B};7mJsJvz!5a>>opzR{OJQnv9kc-g4;Wq=FCo$+a%U z*XG@(@~$-C9`SC3jB4c(Vt!@eS8_;=W$6TC<7s!U8IEJSRw zNY<8EtpLxPH$$FYmf8QGYBt1UL?FhUYLhisM7c1RYl-M%#6;H?t7gLTw5anvLRBTN@oMt zxi1f%3y`|1XhrI`JbL~NZGFt8D5pTGfkjyeFCV*UGPg8GmJP3ZtoW1@5#-p`VF&5>SAEQZC5}W{lm_GzUcS$ zkT$i?x4i5_w36?TPAPvMwHx~S?*F%tehuL>i8MttMMEC6JS(H4V_71-QvPuRTJ*DM=hn?e4xu~k`in9 zMceM&IJ`BHH##*;|9dgj@R^G8q1U{joFKP(-FG*w<)cu$f4VYpUZTEjS(-P)c^K`j z{yev*(r2+BPTHyM6SEKF?4f6Pzf*2YsJ{PO@yi+noEtPLnxboqW*G!_?2;bvqM={&S2z_^5msN z8)(j(;WwtNmVieg*aZ+RaAeErUFf(W56xkmh3VH+hVbk@x^7=}v1L>X;D5=lB1}kL zOvmIveifb^!-Tnm@}s%2``8lXyD0?qyyBwyVJ=Am(zCig_rp%ji-C(R*ay;dnrmu|qx^cOpZqR+5u*s_Fm8_Rgr zTR&I%s{bX8GJA2#jkgZUB9yH!E2-Ahzoe0xh`+09-_P}TGK`;1i8%*j78WD9c9qtn z3G5}qn=#6bY{WIkLsSZFJH$VQr&K@@P;Uo!4auj>Zzsx`0p3|zOYtaF5BvwnJpYjh zc6i(aQP923Xi4+J35BXeZ;tMAsXa;v_ZBwj9!O zJ-KM%9)M@JN-DSb!cNNu%fRgz>pe}?(7ufR(B=oPvo6ug+N=@fE%jczLQ&AYAa<5`N6awPi9)oMPkiw)kN#@ugmz>Y*RF=le*5 zUG+ergN*N?-zxTe>#aLhNX&OGc?T#M@u(s2)^2<1eDDsH&l24E@Xk61@?{ktVAm{E z0k?zm84gK=x+#-ayh$()(|eOKW?{3BU+A}-)%FxB6aNEqDXr1sJBo@^*Hx@S`~D(V zvlaIudBrxDn0cofZOqkPTg0`Em1`HBy6*LaLiqHoxDaGABcvzr`x zpfryL1plssU)!-;S5Yg4)7Xb;{mwM{jZeH;WZ4d@q%UkT=pN05%-q{5gPl5Y&h5Gg zj16eUL(@w$KEo;Vg@2b?O@x^b?(rSZwVq(sOj!o08&|+gO_I3PPlQWATnFk)w7T_m z8CR=20Ka(70~WvWA7m%qJZYhMj_N9Nu+barqt&Q|1TXNcCVEXHD+J@adn~#G6us`j zu8fvcW?!zd^)#D4JgKTFG$fOmigS*zN5Z@8T^b+>DoLo=4npQ}5v53s`b ziq#FC98$aX=T5=gNwx9S-R#X6UT2_`!P>(NuSJQYQQonz#RHY%`TfXiRM$+0OgPe} z@uR-Of2pa~4}Jo84t4 zLMbkV0!50{uokOOEG@;or9cU;#f!A1xE9F!o|$`hH&WW)|GgJJm)$#Z=FH5QV{>NK z1NaYq+6lkk((@_3M?L-P zdJ()&93$aw$Wx*1M@2Lygq_PL<{K4(byciKxeeYzOTf9tTIM~&@0TFu+zsJgdzV=^ zI|`phE|0{o9i+{?SzPP4NMY;DKU-8IIXFi8ocX6Hz4Ol^>3xUvdG}9O7d&5E5&XE>g*cxK^Q zf@dwBop_Gmxr~RwSo6YVES_0-mf%@Sa2F#D&n!Gk@UXN$5$U41B_t|t6~Bd%bF03= zWmWML1FVCdm+Hc*C_jJUzvQoZUH(_Nhv;?rUm~v2p6@!sEppfoy++Jl8=B?PxtH0^ z!@b#nq3&6Y&91IO&Bo9x5LMRM@wSGv7Wf$&MNWh-L6}_~+OnChp;_zo?a>01H6m{!BB26n4I z7*j=Lp5*ase6xyn`1U-q5B2Vk`4RtD94p*?>b3(l>yG^i@6E>U_qqZ4!#z&Lu5ixR z5?mjeJX``?!*JfcMa7oT4-x0Qt?0y!@j{Jz?p5Gng9JFYu7-yjVmYV>#ZOxO?fUW1 zN;EIA+n4^~?%FH75j)#6zFaOl7$afuZtn6B`rAtsiWUq(tzd=&e0{j_8 z%Rud|T#KI!Di*`=+dK)M6;;4_*?`DKkxSPVKY59JNIyKX=fRGE%3=987T;Uz2G8*Q zb7LrmeN1KIV$I=b*)q#vpHH2p1a?5zgOA4Lbz9?E3i88 z%B|A<FibDy+F{JNZ2u&JmE5!X>~$I|H_TTf%$JB8Gm4*tu)Ob9 zA7u5%y#gh=qLf>0+*20zyKB&u>s=yUzotDg;lr93z536)uziMF9yHd$&v#<{U$||6 zU-9eJL=7%28-rem8VI^OgFbonXV+mT7P@&%T;m>jPVcg6I`&81@XPXpakoKZ*CsVx zW>0@wBcK@f<;!cv9sUaSt1)_t{ip9~uXgBn7YKih7u*9Vjee2YBND$gdZ0SaLpQxU zrk2}t*9WfmD!YdN?pERck?PVfGyhw;w|pv{ZhE(8t>$#*sok8OO~d4xtX(g+$ht*t zcTH~YkpaH-iYlHKeXC$!(7or1Cjpy!!hWIe#ZOjlcRMY>21@k(yJ*Fev}e3T(@j|W zg^6DE;TLEg*}RCx6}PEJR`>15qQ5IE+Esol1b=N>R(?zHB8{R;*xCwrO|G?l+_(Ej zdQ|EX9=*K@ZUb?HrB~Ecyz7SZ<`uf|cPj7Rg?^DR;F)WeD>umJQ2b;veq-*u^gRdP zPg4F<*DgnItawrf`;jJ`o2d^yvN<%p;wLkT+u^$pzEkwvO7JODA#9b%ack=1{=(Yu zSag9Wf_^^~Bi*Ff+kJcX&$AmVfS5p%I!Yrj0v!bg!+-w*SL7O z%&LmtDX0_K5EvYXC7c3lrv}@dsouinV;X})#q|HRSLA>1QB>(mXxJ^Q&LKOMwC<`4 z1)Rg)Uo3nq!fr}vKChSJOvSH+xt~2%^u)TZ`YV3X2p)$jHJ}SMi>!Fb?W1bpoAI0T zlX^8glT0@xip5Wc6!*amv;2F%;xPO7#A0u>y!MsrC$5o$QR~tf;WL*7lr|ceehK@9 zV_M-;;WONMP*nNjFB<+;L|BszFua&}DB-SWJ;*D@_NuE#7}vqmVGT{akstN)20YEb z)93m(irMF_dd0uH_f*_+AG7tQivUMG{wCq+jwcjPb?LK?^w~!G43<90b4}$cNuTwl z&sx%FP3g0>^jS~(^p-xUMXKLO`m8E_R+B#Q!T$Vn3|4=e#b29m)fy~1qru{D(dC%* zT7%K5wcxi0E&eKtMQgSAd*V$Hv^tYTRAh>t_&;Ct)QE}#{4b}g#P$Kw_W&_K^bkeS zLwXMk5(7mKC)i?oftaH*+kyg7M9}8ztbQg#CbePKqCx4!qRQ3E>HZpRu75^4S`Y-I zNox=@(uK%gF$qx-Day#?u%w8H_?Y;}1bbRPr?i|Lm5It{q<0oQZTX(Iwqm-;)Qvv% zI)he;4rf}k@Q#7%ADR@O8XwhJOxIa0N|V;CH0koSda*?}v13~?%&5_dT63PtY}H!D zj)2kvbr^0sgUM#~w^$4GHX1CoO0PGn2?`p=dq%oaXV6*243$o=)l}tukV;4Ni%AHJ zN(${I+N(Rmv>I*dEPKDDH%A?wz~@FS#2Qr^ogq_9>=lR3T4?G8J<^n>^c-MdH7aQo zGR&$RZMrQZLu(c>*&?B)Q|Wah2sI&t4RGmN<-%dT5v@kitW{|+rI|W))pFXSHdJC_ zAfY8@U<4Rmpdccja?0~jvct{OX{=fPSz29YmK8NiW7b);0CO=%XUS1n)mfq!`r6G? zlkcf%i)rWIyvwa;GidWoTD4WH5hD^JMWb0XsmvCdVzbfAaE!F~kXq&Vn~gbaX!)3% z#h~tt0t`029`uV+(loOCKqCG00xd{h3u2eooYP_uJOkQmJOhH*qmaMQC&mVAFkNTx z*Q>B1t$rY4o<=KF;c4NkBM)hO&S=FbO{z?-=!KCcevlYgRbbeS=6~at-&f9vk3-yBiwT@S%+cl;%>}eB z)L9^}Je@Vmh~z9Rx*U~3q_S#^J;CB*uQRX&(Q4L$mQ`RhU>Cz|IVKVHEIPacwp^VG z2_~~KU9Zg%^Rlp_M7*iB77O92DKMyVbZSwf%^<=N)4_^>wat)iFy^6cqHd{mogo+N z9=K#7SF{$Gv?A(iJB#R^nUYmz71oDY%&}RlV!BqenZOj)Dhn{T*F``6D-zNe(NIYI zr}RLv&gcw;Ir>85Be$c`S*$99TFb|Y_u9FjT&_%Ca#RJP(V#CtMT1p^fgY? zN^^qkJXB(@l!1v6m?O2(WT(r8s1U zQPiukjLP&=qvRG*hK#&8m%hw9M!qpAhUch9&Y#k7LPv z0A#C#4RNWu5W8BlUIoJCGl1-pI0GS-gf04L?*Yjp>a0Z1=olN_5_n1NGQ^$e)m{b) z2x!n`&0-UVMNO1y?`ozlS8EWc4UNT#)>c`c@8Za!)vBuP_92LX47;bPs_926}2zVbw^Sm9wr) ztwC#MEY&U^N(d8-gUnM%eoEuPrtcqN+L^CiE=iIG_pSaD9`-tr$E3A^_8I5WsH`eR z`kcniT1=)@v=ro|8}-Dpm{{ap0lk9U_~eQZUpB2=jtgSvwwAOMX}|2YTbYYAcnN&@j%`xu5Lg_Yo_UeE&6*)&g-qXu)tOhTZk zAi*_I)a0=b4UdgTY8Uhmb>-Z$_08JhHfV@It29b%1=z7BdY9YE(-}0zJiZF~7|=L_ z8NdW1lCsd`&^s{}h!xRGRssSP?SevrJ38UbCFXyF!bEXETPT+*XhA_D7OhCCDV8Xy ztb$`WVW>dYmKc`NiA|K4392J;ebXWERvRn2{t>qa}Tg(HVe}fm*UIs2T>gw4SoH1$jp3Rra;* zJiMr`2g0)Sq%5GW%dzFqM1*wWX#T%~UqU>y24MP04Fodygg@B0h8Pc@cM{{o>$w;r zMHVSCR|K<%QVTw-hmrwe0bvJ{RA3T;z0zQ@8Du)Vtb%V37B)d4JRZAKX%n|}b=7}^I zUJx?&HNoJ^@W^(N3Naokr;{z?oDMsK>_*UtIY$S5i1aj4xbGlKZI1@-9d@^M~x&hL{0R`w)BgpjwGo3~iv|}=2(a>^)=g9~?75tF;R)&kA zUoy=(cpV=e=uS+f(OC>_$d@4(Y|CcLpwZ@&2}Ovc)1Wdslw>2bi211V-cj2U7b8u? zA(5O17PUm?79wSh7&)gn(pMe5KzkWrq=b)tL`VoPL!I_wbZda(nQqG@qG1#S^DUQ* zJT>er@H{3HGi(MmqX?6c)e&{DEE2*apj9iw655SaXkmd2K-rs2IiXE zb&`H)u|oE1GYh0eLbEDay%C(ZCrd2fk5^F26$n;2{L4XafJ98IGhYW;a29ZZ5~v92 zgt}bDFi9^j6fh64dXOQ6OP`}=UOM?O{xRJQt59nunjv%yKOP2wL z%IJqlTqa^IA~lHNfxmGe;FT?_F+vpDwPse_xiRo3(sG>|wJ>wo?5?5KbeJ~1t<1lRzW&@V-8Bu25}a+i^+~B+}Wf!=*vlXV*NTMi%3)I zPDy?TFEOb-a#wRmxH<7W$&(~0X>7*jqD+a#py-%C$}Y!M8u(_(M6(NIrZqF}Wf$d6 za^JBKIUfSK$bJmg0<*6r8(*WfFc||)MaflYC0`NflM^cg2(I~aIqoo~CAM3ttlXT; z5J)WA8MK^8a>OF&dyt7jWAjK0c@QQC>dz0;P3Vj?G8vhSNk5r$UNso3gsx z?vUgPBMjz$lGGN-|D^L;XLeROaDoDYIs|kGpzR zf$j_{bAg}atF}U@WWo=m=03j8VwlPxuST!}t(X#<%)NnBL7lHsB9V4q)YKN+<%my> zjm38oJ+$c|y$VXDL7S(fvKa;{tE9~Ytr=2G0)aFIpePjZag)c|lEwCQNFnYlLJs(X zzKp13BAJHY&dz|nZ^%%{PzVDxysKTsxL!(l&y;bY19&@9Nqc+XfyNAQc`ZXaLv6MA zS&eyWr2*CteA3;ziGipnrRSuVN>|1tC|PZk;X{Sp5SX467Z*vN^2qUF)M%}IdjNW^ zJdGBsMrVZ1YtTsh7;V*ROE+p0%-CqMFubT88Zk;!GUq((U8`Bn79{1MdpFUj*MQBV zx}Y_%g{6dfZ-!nbq=4o!Y?vTmsMhIqa1fZa@R*SR0zOWg7Y>guQ9=gPE-!DmaAo<( zxSs`USn3SO$Eqg3w4cV?~$U7;A5M1#4Tho{D)d)2PQzbxIWg2p*EAie+G z0a0Yt83zZv5jGD@gZ&HWOZv_{%lx}Pni5dYX0S+(1#o|R75kTeuG<)@+IMwCX*$Iy_m~~n&Uixv{|(hrmn?^{VRyE|HfgY6;IeZK< zkNi%if6gie6Q>xxV&YRGlHx;SmB}%KB9tlKoEZnfFovHm$6IVI#)ZblCWI+NV`HL7 z9w+zlCg~bLb`&**&fH+c2Op55IjEPT8j$m^~ za*>TF_^;TywP=6uDteJE=`DH%i9TXnOgy3HE!gwRmM5)~O_!G!#+wT;2?RW@aHIHm zizd<6-UM~ai{nq*sj~Ud2LJs<5 zeJ@GV+!AuE4VXhjcdvmy~htIc19obIlw4FT9lNga5s}Gi=HG=DZ3dO8W2c#CAlRj`DV1 zDv_d-aFLfATw{*%GBvVwKqJYNFPh-8Wt>)$Q$a^LIrND92UJ$k-7feTLD)e%!IlAu z|0BLm@FjYdArbD31faL-3|#9Kz0%d$itg#z$Sj+ekw-f&j(#xvgXGccZ~`|$7dhMe z-|I3=oZEC*1>7d#a>#B}l$Z|(_mca}OIrlm=Z3jTVo)f(EW8-5v}VfW7}87h{~zHq zVt0&_qa3j-dF@~c(`t1#Nx)5bb_+iE&c+P#xII%&Jv+gb+aCzTf9Vp*Oe#X11_J^E z^eV$GAkLtNaCTwxh6wb;E*V59#jx1rVGH>6thyXxwq<*OWgNs(MK4|qKv1x?6ZwHv zGyMfNu$fzI&@ReW6aFvlIB6iHBK=zvLJQNsb_3(^KlT7MXpa6n?Ei)}f#vH#vR0Lr zESnYEwT6M9yPA6llnH&rQnUlzQ&#k4#g98Ugccyg ze;;-##7F+WjSer*#vR1;ud|9W67*cAufB#_SWy7B>v|;?2_!jbreV>k@qLttVpJv% z61#RIPc2hDN!xR-OG+YNg{6xKp@aj%UpvF9l$3>dGS%Nn@1qLAp{SO zWa^hvNv=gD4{fG*=HLO%Q19tIN2j47u)kBjL~zJ1L0|MP!Lyfe_UlkS>DNlRZGuHA z5o8;JV4Mv<8b6LXa}=@h3}Kwg*a#9-XsPQ78>fOmWZ>Y7+z22-^)oilc$n7x5#~KW8O-oGAb+~z8|eB@XoU7 z5pjtr17STSrlyo%ASO08A_{ig>x#tFc42HpO2q3*MZ)!~Oh`>ZOXT}XM=U9%su#KZ z{gl`dgpthz7Ui*?psy&!zFL%e)-NxwJTjn^Rc$1ts^LPuodRI72*FDjm4T~7wwp1jtv%54nm)p&%>UERY^pP^C4#V@thDSlHH9=d`B^VoD;!LBu=t0m!-ejWb?=FCpK;WIo~<%fD|vVIVvv0 z*6K6-Gc^8E{cLP{X!ZU%IsVvEH^49hm06WpwoEN`+&_!{SDJFTrTX9MKoU?CnA9E^ zC>v$m7A^s$aqCR@Q2!k5%WV>A3HBH4zo_(i2&WVgL!PUH>=0nUIxcQ7FCYV{RS-#MSfF3L)?Q$6O2pkNT$k;(9I z+8m4IXGG|L2pNE$dYh=SX(%*^@ghrGo`n5Zdl(+uu#@;-3GB(CrLpEJv4Xv!JOa)uyQV`u{d_D47y}U*P0TM+2A-#d>qPhz2~SV#B4K^um}#R#p3CrW)*&&%^uJ{CQctDF_Hd%OW{|Uu0}(RI)MfnQ}&Mt?IZ06m(Ve^`C7HjO6;06HE=p9@`?<9gs)Z=V&Ucjs2C$f2jTbDsv9) z*VytEnFgCym9ERm@MnM_yDdh6vpRgIX5=;%5(C7$j2n%INo8fU9h01(2n+~rAMBqR zmfYT7=q7JTD7xF!mi9t7`d`sqP8Co}(LOf9AELN)Sr#(mXTa3*_z8LWl07K;%S^@#uY&{9n6JWlE~MHpv!KiX zC+J~1A|iiFHps$iB)D9EXDrN4Ydno!@eSbz)E`7(ls0OdO$x$KsmefU64)}DB$kMn zsV*mL#v5R8z>pyCoZL@-Vv;D>2Tfw@iLC4P(3}YY7C>RgU2im+P|%CPB;d>jfJ;Bb z+qr3bHfxdMx}b`e#js>CC&UoUf(>JO!3b_q#z#bi zM}%{GEKMq-5IM~9AdL#4!Qimua!%v;4_M+jEGgXiYPQp6e`9(DOk*CwLo_Z?m6FB| zijE z*xyRk-Erye(-#>3vhA0s<%Bx{D>(pV>pFT$yvY8>I7G?Huc>S2CuPfUKr&ofOXzWX zL?p>ctPx5tTenona?9Ak@WSPmp)7lQ<+M`*hQNIxOiXjz^R=>vOCVXy_(?HMlB{G7 z31j*&MR(Z+AjSKz(0WC89>HbjXcC`6A9#H(k@B!{pALZ#BP+ehZd3jn8>O}W3 zn3<-_qao$v+5&gmD8r&dlaeD+Xs?G3vRf%EO%SU$S+uKxf68Lf9Pg3@QW82;m+C79F31~y(WY8jR5Z7d= zm1vRrEb$JxO`16B1e^~d`N^Ep5za|yVGS1Wkp|t8ZJlExTN{5e9Xq(9Q+kF{@0@Oi zA0^p@}=Uy;1q?it^TZD`28B=R7U-OT(+6l05{ z!8*yn(q^*b^reepuZgfwlB<+hA@jp}k)4Ez8z5zJ-xW*^4a`Y!R=g{^6KL4rP}(qX zPAQzdV;u9!sa+PP&8lWVogfg*uBAbig~w`^#*tw~IF>2Tas(mSrly-6gajN=Np<5oM`e8RK5$NI*~lJEkHZj6<1lo`SxiW4!fro25XAq=Pl=Y&DG;3zbM4huIFu<-*3Aw`bUwjaCW!GUag%FhQJ zghV5p+^mDyBkjV^1%$H@4~{nr#?@;xa5N4PA8a6m80pRf zi&jhB!d_!JP)A#Z zPGux-gj9l`q;R4I4G>^+r^+=V=%415%?)jAIME&Efl6Vt9n=yjAD^S;!Y;NVie(^# zaCwceqfYGfy<;Bqu)+20^fNzyj&l}LH)*~lHHq~{I{ZSrH1IWm@~k*?1p}9FH3Hc% zXqnhAz#-3^bflN)Wh^y=4P_SDT3}FT;Zg($4(g)7^V;E<0q&JRiu{hzVwcUtV%WOP3il{NuMioEICB?oIZ1f>4IR*|a$rtQAW-?B4yE5%-^Py4V^b^&W)1)&= zARYU%#`@>waBzY7u+Wyu01;7MJ^B6{86G*GsT|`MxT%HHFJ~r{9?sV)4VQ|r*Q#=; zFU+y+H0?qPcHzvVUeLiL)Jx#R$7@*Z3!T`Q5Qm*#*wnHg4-0`#`WUo0nP{d3kO*xR zIx!nV9XU9#J{ZjOVc@Y;ji#FKov}Hg(?sc7Y)V+jk;BS{YVgfUTQQumCYy6;PtwjG z!w@QpjWoF0A#z`8619pNwoQ7tu)6q#&4?;u8poMWO%P^Yt-uE2h19Fy26$m|xporndv zh2fwIn=mHAFmI$-A;6JsDN^WnI`}*URVd4+?Gu$FTCYqg*eOF0Ktkn5OUfRP zC4}-}AwYAv}|2 zgPb}f9O+CFb(~+A#OjnQYw4i24U!M%hOwGS_ryRYGjhg(Krm2w4()P*4g`T(lfmF{ zmJ(7zQUhp$a0Q5krPKPLn?N`fNpcS@@H5~vM{(S~bK;s#yn^4zLX^PhLxyRmKQ@UD z-dZBv?%cQI$ly>Fr>s)?izCMlD+9MyLFAXN7s|B`#M_t6hVzY72*&TIk8)X+o;I-Q zMio*w9eM-Xx?-ckZ_AMNgLuB;X+cwvmEiQwjt^p9nFb=KYan~+ND_Rd28kLm8=N~Q z8#Ao9A`ryDZ)$NWqe@38DB&6AsK+X?erUDKj|!f~)mN-)Ixka#x3NuU073M$hDB}> z%5ra|mOxJ_<(8w7b(F!{WJ3)|BKOPkE$tG}<*+m0Y^O(ia0NEi)DjSr9^39E`bAqd zxDd@&w!aye67Ys-BUDFuzyTlqHlsL+bukNhG)@kkSMDQb6ce6_Q6mQK$j8-YG}}&j z$>7$YX42%iuLtF^&iDo>V??-$0Y3O7+I9CEpi7&?ZC&;TB>r{vH5yNeW-hz-)Gk!?$QCEknKA3k(=+7=l zl9D9;?C2{7T@6nZ@qYP^2iz>e8LeZD_CXSfBUuv4?@T@HYe}Y| z2Ut_!IHW2I33=E}2P34C7*9+Nkqqn$iVBdFatB_NCr49=(kcC;g3VU#5>cP>Dn{!xvl^5>dVZQjpl;|X+D&ta9A_gcUl9CdV*i~xE_(Za< z%P*D`5tf>i9MdlXrMxBB$*4zxSuJoIAA2_jrLe@tVfirE4UU77uOm-QF>{EV!-&Y!&O+qm2stT0u0$Tuu_Jt))C?A3M+8S( zWfDYo_PR6Mv_%*{+Txyc=uP~XfizD{Ee~bFJCih|YO`D%NjTjJN zzio_$nlXI2eO$Weh)1E;$@GD+;6i}=Fy*13I*7+*mrKI?#&!T@i3S~%dDY=;V*yY! zUI<`(`%0Z|O)cHkY?7%vKysBYOtH$B6l4XZbjNNikk(ShAAt?&z{igHoBK)OcbD{z>#d zG(i)wvQlN71`PfiT=gQyr#oeU_fpUZB8+sn0>Xi=Ka1I^ky@f2Y_%nZwAWDZ`RNZcqg`f}nZQN|>`4!BSv; zSYNci;)v#v>+w)brwl2~2ilRup|GKd^?~VUb`|4OC37Tdq3iuve4Up!EjlSxnun4# zoO>&kBlV|bix>!6gRC=jwv?{UlZ+RC=`snXeL=ZWumF6n+sW-R0Vc63W-xK1h2bxi zA-bYlOs3}#9gV>;8 zc+iz7G;*|4DBXch;(}%Xem{6wVc0Nf?m>NIx)7<95^u%gbdWo60l7PO1N=lnyEDbP z1^6Jy5RMZIE?Bm|GHEKkkI1h|2S7la<^rc86dPFL74F2&DCg;8tBU*9v3HCZEEaQS zR&;04hEUXjO;U<7G(4Q}t}5{}`@l$k7^wR4Xt8lAQ?B$Zar2-=9X1b8vncSCeeWs- zsu~Oy+DoIoag09m^f=88=O>adT}sD%D|v!+?gMLaG+?{9xb#F3`MVo^$8uuKmp1EUASGcycgZ(l z<=I2}xHf#pM}6Oc2u|DF6RsY%e+A3hmoao zVInvk7>c!k!RES~WZHpwD-)9v5+jmuLM6}<(S&0U5n;4I=!OAhXjm8`0x-TM^d&&U zFF>#xQDtI6bb}a=fH*p*B3qA=E0T8=b=uk$0@DAbkpOIdz#aR;B#&vRA(3U30}DY` zTw8d_Tb1Fl%GiX2KB4(htWR zFy85`rLb}RKfsWO?LXI-Ru1e1&V6zJ>)_~~oy7EHO(j7@q9RRk|I zWJ6Ju^(Ur~&>E(=Q(lVE2rNcyA)|r`B7|5Mi2~Aiq0f6Ejlw`+7Pc1*I%6(&cH?6b z`mr0S`1OKa#hA#r6dq}Sv!9}etR_nqgLM0z*34uEwXZ?kUnXLHdBe~Lmfv|8CQc5Bpq#Yn6DMORul!;+M?VXv2wA!Q%HHn9o z)}b7N&VDl(=EaL{>GYQQZjLIOt_0?r@%G($^wg;}xh&jb*xhv$rzI-+78&sfRh?*v zrWjs4#`FBIds6dvyYMSS1ce}I)n5xh=G)Ew$dl! z%y2sm>?wFCP@U-*H1hJAUwV@43T1Jh~9)>Cw6$MmrVp=Dq*fZ(#_X5mMZ7^f%q6Rb_jBSVyzB;Bkv z*(`YFxKJM2QsO!*I^_zY`!j7cj@Tw~|g> zp>>R37e-3@j?f{3Bl754`S*4W8i-XY#-bqNYn*(G>DPmVPUi&?0LOY!UFx1!-9hR`$q)@ zAl6HAF7Ut}-3Vz}31R+5v5ywJX34r7tah!Tt(cr`^%Hv=@ly{t;v9;7S^9;h@IH#b z;J^-IA7i@Kfa_fiVn6t|o$3KEM7C>sYO-y%Og|0n@%py!Ahrt(3Q`1jXx~nLZx_@- zen&rqK&+R*PMty&fkBEOD7r2v_x9j|f%pj#d>Z2E6G!iaVmzKEPpfApo*Xe|daTj&k9QKU8<``Tt9)MUnIfzTUm_O|JTP+O*uj3XflxPUR>1bDGg`Pp3EQNDP^(r7`d29sEmXPcwDJ`SvZ3TR3>(i zOyK`YM0#PD)MzHYgq4b2dg#)mq3}RH@SD;lVLar+V}*4(g!s^S0Y8=|tSGGZ0c6nDs*{3!5oF#lj8S0M&5e-u-bq-^e? z3V_0l4RLm)gYifUomYdEWQ0s%FmVCcNYUhH%`pKY{+9saEO=LuRuaaeoc36DV1N)n zYM9B70J4x+2oI;Xu3|e<+?-N;A>$E;jhIP*#~rW9N?0e#xI`8k%Gv@bI=)EVWvF2; zC^!|dzib3hCJ*O}!M5|@0-(51b_!E^k@d|5fGwEqvB(tzTEUo?k%A2lewhCy&u@3pkx0+RmvrHPP5EhEZo_lBrg%$_Tj(hD4mJMUMAoC z@bb}{n3tV0WW%pSVpmZvJPg_yxw4&$I;S~GVr@%h>9!SIxdd~>ktXk-+FjwaZd=%E zKt-isA|-xj4H_W&Mn4(JHUgYr$$nfcPq_9lcJQuC*OOqZ*ihMVDAOKb%B|7Pr$ZYq z$L@!|jBAS77KpRMl*~ifmx@3a`9w{gnQ6W)L@^P86!56x&Rq&0A*+o=1*XGa2!pL_ zmep#qboTd$6>Ra-s}Pxqn-VmBh%fWEr6U;5=I_hHZ~d9&;_piZyR&2RLJ4b+`D$sB z$<|``xs*7w&PGB>!Fx{DI*yF60aY^V7-IsP zkGvJkhfFpjFT_V3Mk=z=D{!`QfuJ?=gwTn4=|jYHS* z39$*G;ji}x5+-*P4(!c1cW$dU0wxzx{2kL z_KRTFV0+OI@i2ca+p+y0X`g;!3_I{~iTj{%V#+E@=}EH{K^u_Zx!N;u@NBva6v z`}b%Afix8sWP)s*g9?j|iH}hBh8C3^n}EB4(2ne=0zA4n5yFmNd~P-wm1NjbH}M@l zUX#V1KrcW}N9#}ePOu07IqEG+O$O!TZa@2vY{@=cEJwKJ`qAYpSbNguE6SpMsR-|n z=}KI| zfJ-5gkXCwK$aNilY<5V;zW0PGf>fLRpcDDs%D{z80C{5TRn6=?w)Zc&e5pRs0-GFW_+9syz3SON>JXeM6knU2}lZS+Y-k=PS#sxg=wj!-i zEL8dISDAD&AyA(4O(k5USUC8(kU(jTqdyeQ1PKZDWTAXIf54>-EqA_-;Dh3rDW!GJ zY=_c$UC z{gb0&!fCG%KireUWeyHLNxy9&!6lU%7air}mnq;uV%v|1X=gFd#H;x)TG}`5S=bbm zDf%r|I5`oiZnY5$1#|t6C52KAI#dp67J$CQy15hlHT`F*Ggc<4*?b?GQvA#qVyK6p zCMkrc3?Gzsu%uWR28LuDU-%@~coJLNlrAl88atX}`v@)%QJ2w$p0_!1n#nc5(HsqLD02p^hv`lLU~r|*iI$K^WwUleM|wv(`(mQ(r``hI)O!bF1PRQUAt%IQ`NSB?MLP( zjvF`s($Ju7W74kd5gRAn?%AeS;Ly4E8wx8u(ih*E-Dk(qu=6t$A3VC7)AEBvpE=6| z-W)%o_Of=#rUh5Mi!LS$YpzuA-??)`r6n&kBV9HhPgPCYGbOaWb#aR-Uz{Bq|HgyM zmc5#__iS-T4lWBB{(k-Db-t^(E3iW0AALJ%XWbihV&kl^NgG=%37!@D>GeM@pX;}4 z?DfdzOHv+(?9{c6Q~Ax)xYUb!(0A68vw>f?Sv>2H`BUzloSb?@6Ebq`z#En7H1F>} zyk*RQ2LqlBpQH7z*3RQ2kL0(eys~`L=~TU$x4v0_YT$%pzrR;+d{)QKS5t5H468dp z*U~?_(CxFQpQ;yoUEh6U!Qs!(9ynaD<2%ql49%{jEW=YzZ1os+*m zSFhdFsuR@io4#@DFznRl=CiMMC;aSj_2r0a<9B>HyyfJ^1Hv}NU(fkjN{4#eTeN$cyz$Rc-gX zw*K@|dXvMKjy@Z`f8CyM*Vi5Y*2m^;wIY+MZ#M=78tc!_z1a1BpPFAS-M?+zu7`%F z>FX~Xah>r?4Uev)TJ>^S{q~i}=6U1ZnZ4%vT91z=O}l@!^?_bLM?Ow!kP&{RN2P+G zh~?eK>G!!M|2=Q))uWHMv|HKl@9|@U_svObU~Os5jd@V>WX-TP-?gjVrqYqcH8cJ+ zS@(UlBW?M-qOp@&4PAM?(VC-?Zwr67Rv*#lURFgkIKQ^Xcb~X4IJvye&yU|&a&?~f z@Q;EGJJ<9}p0}utsr7eJagPt)s2cg(RoG_m_wPMv@#f(u_q_XWxc^xDixw*s*1?sB?J;NeKfXHZH_hZW zr#HNuyr{zQ8%s}weJ^T)S|5o-+ z+wsktPt2({yKr@r__MC6P{*9?2eB2d^KQp#n_vhwZl8^+#CGf&1Kat{&?KW_}7N|+dq6Gsn%Aj@hw%# zuir+uzcf1N!xe{{Jp8!%v@aU2Ube?`)J0ADFOMrIFZi^&ZEy=O+E#FFe$B)QU#2Ct zkG@@yV(aGiFlf5ZhqXR?ykV>2;_)#rmsx*|oA$=@Pn(42w+(6)@gjPHYpm*8k0D$4 zO#k!4FV=MZtHP6MKWcua^{>s`vhn?&s(ks^w}o~4&rkm#=U^MGYH-&j=p`S7P-_xfqa zI~TuM@ndF~yV=&-_{$;F=x^rMZ&*k1_xE4)SXk6>a+{ln8~6Iavh-_l-zL?YUHRwyD|ZJ@oIL-xZbv3h(r&oa`PV@S9~|!C)h=&R z?Q6eZ%^Q$ZSqkRHA1|{@gc;&G%X7n8QM?b#1qUVW*J6`0( z7cJ`G`+dvldmGMMw0N{nn?_MDH;oiSU1xvru=bOi(JQ+Rc;k}+Jyy2-Zf3KTXOcD-0XcH)g)M=p&SrK{@1Aj}=t0i#MKmw7?iXv-sGHQHdFUH3>P}FRslGHNARP{BGZ!HD7%G zUiGGp*PI(W`c!78S@}nOAHHRnWpBHDpnzGR^GV{$(Qd~`K{@fgWclZVW*!=-xo}Ej*5uyHcagXe0KaM~4W>)Y{ zbFHZb2SU=Wtxmi=q-SwTyyt?Ok1g-Lzq-MlkOohCj;rulo9+WaXnyKP-=4bk z{?BWMwCnQSz}s&h`7L$LsKlrfjs7gwx9E~yC35oF8@Gaf8aHEx>G;CiUTdHAovG}1 zZCvNT0iDNJ`C!F$L%X-!cTTF2v%GWR7ngf(-8tz+MSt&@H+#oF`u0JtN6@@F3#aC9 z^Ig#F%zUxW{)hQ~tD|@9aCv!jSw`rvrf<)CQqajKVg9^DY4`87{Hl!8-(659&8V^~9Rf8 zu;H8JD(>|^jyE?e_WosAok{O}Z@v6utwU#O&tAFhYoEwEjXJi>T{gy+vF~(kmk~o> ztv+o2WWVKSk9%MAkDAx;&Z+th8L!WB;7WhAF-+WH! z*|n{cx1ap@k6Zhmt)I3eqFQ>*yNxRAVwY^|`$^Yx!EGjV_-OXL#8-ZPAN`Qh`o)Et z3+oO~o0iw$a{FKWf>(VNGqp~{^&W2G*zuclXI;8l@9~hqF9+U=S-R z$G`mL{e6d5g^cPLI{IW<>)nR+Q*uY1{OjjE#*@tkR$aT~^0nq~JQ!QBvd<~qfqLs| z=6y9}$*vzd?HlDX=GCfCfBUF@t7^fEgAIL~&REePW74kSXS=t(U~C)n!?6$Vj;&B- z?)8mp--)U5d2_$DO`^LW4O0v>{Js0}xm(L;W%hk*)tZANeyMK#Q1wH`y-F1?(E1M< zw#&tEe1hA+ZIQ0$S5~R~$F2jF){UHAVPb=XiW~dZtNB5fBehOWoL}Seoz&`@XN{{Q z&pGX0Rk5&Yx2Pf2OrN)I8nypgv*vkA-|}uYwE5T7{F{8Dy4`r!#jhGZD%3Ul>3)a0 z#S5O)Ti$wYomsJ#+HVZ%TEAt$t2ai>*w`TM+K4wVMaFeJ)%Jr`E zWw%=K!79&Jfp^;MAFOB{8<*bloi>X-JU+TE)_>5dh1Z6BpSLb-@{Jt&!h3kt?p_a@ z4p;2XUElWOpC0*rvoyqi$Mla)Pi_ntzItGD%SY|bo11#h$@5LxDA{h-)ozb=Sd@bR9=Z|_!$dK}*~VrQ#y;o(7t zLM;Po_4K(O)2rFE_rnsi?xke9woC24#n!*d$?yA3+wnAc^Ov2IuDmfa@x-WYeQ$QU zGU#HmIC#?SjDc$>e=(r_tUuD+{`MX+D8l%5j{i5xF-bG#|pQ?vLZ(qCOfAiRTw{J}i{_2mdLv+92 z-B|DCk4KNZSg4=>YE`Aw;+ThE#blF@w@J~?l$3Wo&J&c zJ`An$@N?e-kDkw+{^U?`!sDT7`DglvY&uMWpY9pub9P@$ z&xSu9?AL$S-(BbKUOMjB&bc@1>{$72+<`@VKfp}w|LI5_uypS3a;E~r;A@1x$E13!89$b*jqI!u{fS=ndW+m~z1(7k{7gFinTGxgk)Uhj{K zsW7Fm<-Ygc(|kOBd(8pkuCHl6=E&LeV^a>!nV??YcVg#;Z%(dZJ~3%=(Un#6H;F5M zsgUvIGs72Ojm-aJb)UN4-`4%w_>JejZ@z9g_TCErKiVzNO|^Xy+T;6Wd%T}6eh}7q z$(Juje*W3~ZA*(RdkSwfsgNuv>$0}i`t({cYg4uFugUT_wOJWm ze^aH$$r}Sdo%O?psTa14ztnW=*|!I6zukVpHd_CoflV5XOAij(oviS!uvf2%c$oL@ zq!oku{Wvc)!F}qPpJF!eIx_X&{`@M0!FyvI>f~NB(jITIwL6dO}R|%h-d#+gX@qyq~X=!=ao9gw& z7kh*rUs!X{p{1=R%)MHF(KIn~-3nFSs%^_J-@JFD=)uia<1g&iuG@R|%hhRVe=Ld& z_d1wu)V(z2uFekZbZ3x{*tSaLYB?R7)_o8hd2wCkw0*-FxoP@@ngthDd3Lr7&*mHBu>EmyF>?2Id4|tf>RgjtUCDP(dU={oO9s$qaml#&CRYC zWM3#u>A7e^!oUG_Yc^=qvVN_zrjD&X32oVJMfOYW^+DH1dR95mU(>ND{`1wdT&^sd z+OWmJ743$;+~V`?PmfMAUCiEr- zXMLQXvSn>2?TVFs7L4ywb=3lo{m%=lymw%A?S!;D%9{Fzk%xMm$(dGjmo=>Jpa-rk zLx10C((fD-ns++tRPg*t*A+AN77EKIOlY#D@zl`agEtS#T5vNj?93VcpymmR`pQwk z)jw4h@hRdetM@89vgU3gX$Xl1Djz9JMK&|VSj~*;M_-y)wQUrW^#i@6WH$9kMZ|ZbK z(&l;XXWiWVR?(TomHvD%>g{iKX`>9YqV@iZlWjMH>vmpMxk}4nDXrXnwLR)wD_Aja zS@f0(j~`kU znV!}^pz9KOz1N7mmxBwlwdWrW8nrj1O7dU19iyMDU0r44-9>emv^&^is`+KBIkf)g z1ys&!tE&0eroL4^YP2V(@&^xxnK~>}-}-#6W?|5K=W2ej@q9t^TPH5PcjoAP-`MY} zY#q6FRAt4+8?%~ipQ)++eY5-Gnqkqye|T^qblZe?kDqP)$F*N``W7C4_~XQ5Ep+G!^YF~2N3OYb zjXGYT&&!E5j%F8DUG{usVF&$!b-hmR-+Zp;vn^j=)t?Ts4Y?R`xW>uz1G^ph>g#|r ztvd@B`i|*)>Zb;(qV0tbH?(NEXMMkq=59J%YuVO~3pcuYxxZIYx$aE$eXVX)TRVBA z(Z5b?)_|{?sdjc#WPCR>^n7lm;pbeoh({Or)IM=%%EYz9-zxmB(z0vY7qvUS@#fO~ zmGj#_6Kc&^S!G_s1vM{kt}$%1qFavpe7$Ct%MkVThkdiNu>s!nbbxkZypVqX_S{PP zcb2&{+4<0YT>m|_9_>4`Mw@u+`?|kx-1h#+_kMVBvDvTbF^aSGAB;RUO&fds?*XcH zaliB}>}(abe10Wh^YPGS7ki(Yd%9cBo+DrU{qW?mVYhT)FU}a+N4}T&P0_}oXDx~f z;lDL=Yp0B@`sMzSHGb_nykg>)p{{Le*RHm0l30DeXJJ zZ!g$?#@k~-(V7h_PyP62xAgQ+-_1YN6`dg_Yk8 zpHu7Z(a+r{XWe&c{%ThxU0VP2CkHaMV}=Lo8{MdsZOCnM{M9AjV^ao=I9vN*?_V>G z7k_y6?9R3sVcWic^TdobLvMb5^5m#FN0#i_b-H8H{fi0rGB+Q|?7wCCuaydW^a)-U zeb%?e>DVS!zkS@>EqLgN3Zc924853oF>~de8HT`uZMw*5>s1FDkI&e$_^8n{_)1pN z+`Q@s-J+^({-J@ZhkxsesoT12+Ur$q>$=&4HuzQ;wtmQp;#0c<4;K}_zwk`kW~(m@ zUb9Q{N$dOSKR^9^n62uZ9M@Hqs(jibxaJ=dGb@|x^%p9R>%D#M8zVMeS?#;_osLbu ztNzK1qqA#lJMr81cg~M&aq(QW<42E8>UHJ#y{GGc%`%KX`_`cb+r|!V{lnwSd25V$ zQQtSbKFIw&)392_KX<8=F{GMHo#KVs4|J>3pB^jDRz)1vH^{$Ib@5+EYn)0MUmE}E6YLhn?YMdIc>5_qcp{#=Yy7pX$HA} z@Kdx`zkbo6Q`ew?(cU8j<+`seiz<`zm&g4JecjjoY=Y_P5n=d@EEn;|(*)_Ci z>)m}1TBis|BC^*uB1 z#JW$pKE?IT>n(qIc=_v|!!B2vwt4X%MV^a8o9Fy|uZN4)Tzhjtk6}|5%w6s|wQ%(2sc)?xFnwmXebYPNyEviv@6ZXUAxp=f z{h{l4lkM!pF3I5&XDwPWu6dnK<2L*%zCZlbw)f99Nt>23clWec1C0wWjJdba8e8|H zzjsahsBg`=Ge4|QZD#kMZq8pDnLEG9)O#Do_!~F)T%ERlSx(*cwU$)d^z&D9Hx13q z-FoNN&8-oh;ooXsoc;E2K&O>Gx2;(DyLsCZ|9o-D#0|TbSM8j(eDULHH{!mmd*epN zy-Qg)jhA+{%Dq+D@8+#Fy!cV=Z5P{}uY0Io#c79r z*l+wfIO^WdpT2){_rS5ayC1~O-7|7`wLK?mg+whMu_~(icfEU#?|8hY_rpUmf4)kN zi40m3zkiEgyxKHwNZ6{TLvCq{2WR}D8ho%#eo__1^`y@)S4?ed{3LbK=S_2)RT`K3 z{m-i59m9)<&wlTEe*ba#`7h%?8ExKCarEixt8$*62+2umbbQ#a^Lr1=8=S0O*Y}XR z;b(rD`SsRlx?NOx7L70V9Ffq}9?BY@_utA3DlGkH4|AT}Zw7t*h!?8@{G-i+B7Q zzyJNAW)(UmH(ULvxYmres#>isjdTCX(A3>!X+@VkD?f2DX!0vv{{4ETKCNl}Z>W~H z+`G=A`JXku8Cb7X!owB*9g{kDC{oYpzG81?{GE2kA{NYzSDLJM>I&ATeJ5;As zY47w%yk&}h{L7~oGDpl`we!aG(7VZ#g8Titan>B&`s*DYuBus~=hA|utBwYyG&>V{ zf6VUHyW9VCM!V_psKqs3R;e`S#^sPUf6klrX{W7+y@Gz$6?%CLaA}$P>VszYyL4$V z@w4UCbH1)yxpCFM^O9a9jPx9IG~-ZqM$V=~H z8#UkA@S?}z?eBjSI=1bQM^gts&ziaZ!1+)19`tWY! z>^&Ry*Sav|>E;u@Zx`6Ag&!I<@=BuS!(-QsS8c=khOfCWs9l4wp6A*;>GSp2=3TDk zeHk$4NQlonm&UiK9$Dk9ug3rI#`*t;y*Gi=sr>){@0qdh`<7)a$(EfYWH1=U3})b?WN=+*&^0&-eTLKK@_tdU{^h zbJNU>@7(@ZDre}pqQUy>>t7z<;GKi{-+OZ4*})S+Yh0Lqp?{k>FC6|ddi_(4 z>b!gZo=1x29@4bU#-F-eA6cWrlw+R{?R>s_zl<@XLtAX9n6hNv<(YSu%9rDfiPH*a zi@x{%b{950F!9qgRc<|Ae1DgV3qH+PFZA7?A6vhB)Mu5h-j`$Y?S`8(e!1b9moM!r z8a;pf=hvRQJham@IqDu5)B94}jk}6}^Tw8^2Q6>5Y1_i^Tvsk+n^607yON*&Ix%1G z%eUS-y|=~iCOb+V-}U*r?V-H7_if$WU5ebuo^MLKv_Ee-oNQFiULP;7bNuLu({;9$-~Yo0H3vQZ^Vu~Y z+;}!?{JF;po%%M-=#($i8t~4{atFgFe|l!d_!W`4-by`c0bFz@`MKc<_>$gX34$>zkEMrZsz`}zFl`IL((xV@99_I z(7lJhN+`J~;%51JeWD(&dgQ4EdG{w9wbZTGq~FqP`_eL9JM_%sM8}?GQf|9k{PYjC!e=(wowv-? z5m{?jJd=K9@@7eny|{V6v}UPBp8I}Qr*vBj_8QvxwT34b=WMk!>6nO!@}=uloNk~0 zmp^X(Vd@umHCWki#<*-XraixA+D8rZoM~}nL+PY>dXA2}xT{h6`#KkV{>Aq$zu)b# zt=k5l%shWnpLVG#A70(``{zTCgjG8*Y1h=nd1ET{sWJBH>UCxpdG?;Tai^a-T(IoN zd4C!;_Pe;aV})+!Z?LHOm5g0aZObwsGGpB>-*hsm-keCsbjs_ zgDX7|UZ?83u`}8=D}L_B15+w2&DCoB?Qd?yFAi^5_<^HQs3MN$=gZ{_R1Ea;Sd_uL_?bM9P|yL;mbZ*53->*o|x z(lq|`;QKe0){bZ~EZ3yd_43WCHK%6l3*UTlJhswP8Rt&=?9{_8o+v)8c-Gg-UyJHI zc~|sfMeoV5YJAr*6$@-Udb4Hvt0``uc=f$TE2~6aeLP`Gbc0UMem(!e=5;Q)32PJ-saa*RZ8?;I_Gw|_WAc!962U;x3$H3-75RcJBzNro3=pejweTK-M!*M z?cO8TKmAGUnyLNfeb?&5rN=%STJ^qcE1v25Rm#@)mw2V*TgyUke%Ws0N2iA8%e(2# zH+mE)lV!_*Uyf#3mG|-YFCPAQ-H^CJoeRz0+cf{!?qeU1+41w&yAlem3tKny%#{q0 zTOQo}K=Cd2oE?=+%K63#DCh?z@`VI_EjJqw00^T3O6^6I``t>N=IJm_CnHYFP0nJ zWA2>ww^cv*<*GyR)jLdBa4qiX(T|Ke5cR{A$bC)o=S=eCv#~!GuAaHtgtFr|+<*Gh z{?8pa*{gKu=$GgB$yV^8#r4h)%)C3-{;e|)j94Ao?9+B_=5=V)>WQ7Blh^BV`Pn@m z72KCR$Fw;=y;EaH)y$HG8xSGIk;e34&Pb~!Wpo?6-N+m++9i5n-kD$#ZS)EO-f zKV4?h#M%q4<=I-fctq;&=4Ah+UcLHd&Q|*T&4_QF9De=NaqU{CIKJ%4u$U6fmS*}Y zXU^$aH|^egGSh~Z&EM>v?Ai3K!lo>n&^9v3FCV`5V$oSC20Z`n^#gTZC_A!p%C*P8 zZZfj{v4-v6PnBkA*CDe@?ODG4tbP82h5bgr|GNQxcwoO980F=$7qy3j*5=7 zWL(|YX0)MsQ_D1sY+NIjr=^fgd_h)h&4}n)u?-@4T9NniiU$07Z7hFe%iF#p>{ST9 zKNQ6Cs06R1L4$~fHb&b&6xieSm?^XHitRBGO&ZtuEgv7-kVgMLoWJ(18R?B2-#Ds4 zTc?hgDE^YmUfvZG9p^W-$3{18YfHJUtpXnfZDSk8NAa_CUwngxwnp><&i;e@u+}Vi zs&VJU)POGhRh2(kwjzI$?N8Y&=Ec8R0;c;>xQojUecvKznpO)Ts>xM$DA zzZvYnud4ljH0kr#+^G{I^y z%r-Wzw*5gL|CJ9?!S6#W{OQn&L54Q7_p-E&w;?h1Oq7UdUJ}de$o|j^|NF@(zCT#G z^*pNa{bd6C=AX!#R)J>I_#jpOzR(gYcl(_iJA8PCULF2lAnR5y@%paj4_PbeMhK!kh5AsRvm!XO0ZT@pNe=hhx7d3*(&h-qd z(#3us`e!isx8IZgJJW|Sx3I9}VRR}*7-xuKNz;dgrB0tEYu2#z>BI7cWlR<3;}mmb z69PY6j###AS+PP<(+iQ$m;3#`x#!H8lXJj<$n1=gHSOY(rkeP|(Ufg!JeHCwQ?5Gkaf%5OCZrgX zp+*X(Pd@zeyUE9oAD=w=z=p}0mHqtI+GF8wliFo@f7{ePs$N!%cKH9dfkeK(*4V`M z(&RZgY4Rg#w^ft%4Qo9ACr*{v2ld0I_xHvAsYHjYPZef-(op@PYkSg^w$AbY`9)8a zv_58AJ$0=5Y3)fxS3j}-9;L(9=X=-A+Hd_07LXPy=)2GjuK4W_O29Wr><&O9~ z8(N0@e7=R_LVVS0r1y=QIoszu{bN$!?z#3ebpLi}+n$BDP1*{uGTX|n%zoo+pDFtd zx8?0O?fh)q|DD6evvMKFf6odVWN%Xb;@!rJ0RM=yb`pTC9m@wa%l_my!4f6H0oiSJg7Z57e;{!7+@ zfC$OgZA-^*EA{$z)+@)aUVr%OuvqJD@Cd2)T*;JkJ`cNDDQo&tX9pC#_~X8hQ=CY$ z{rIYnHsu^yZb?|-d|$`dhxTtq$ncW0TaEvCbH4@0j*c&tHPg<9C%gCQRc~MVqt6}g z)pvE_Rh@UfR;XguJS{)2Q6*jc?G9V}H`$Z@yX&2<6xr0|=l4&HI`M6wi%_|$%_r_PxCA;xn zp`1&{w&~FJ`l%^XSD$@t`Lo6Pch1~;aMX-+tu}XE@p{evPi&gAs&<}NBJ0lTx+tvw zs>zx2rJgiv((=j2Djj_HP}cGta^I=3{}0MTF6S)TuXw8;Tjd|#YutiudB?}(o--lW zj;s}Sq{@;j@8i)qkCxbzuGWEcm&$jZ_-l{TkLUZTX5Po2+`C|2@jM0JZ&Iz`CkZDy zJ(a)F)$#{g=N{Lh!v_oAE#`hObMoOW*>df8X4A|KZ(O|8^T(Ure=SqL)7ACaD(1@Y>vIFU->Q@A#Kcj@ zM!o#`Fz8|GgbDsuQ6p&qs0S1Sih>r zlLK4SdbrcNGLz0UeQ(L~Un(s8b!tfCZ?`YFCu-A#dKs%{ix}0)*QVePSEFh_oj2LZ zS1U%v?dV_ZopZ0GnYHBI8GUlp`7Y|ygRLI!G5t`=_A8?vta<;=#aGMEc%<~9q`8h9 zyVrIeg#BHLe`mnu4%_K1XUFM3z-96IrrmRBU!f{Z{re{W->oF>&Z^sZAF%_r184~Q zg6H~gt2?G}>uvsN?ek?9Kr(E3V*P=8uHVbf-T(J4oLS78_vye77bUk{QR3ggB^!t5f9@5P+! z<}Q9X_Tu&!YhNg3`7}`d^ zUb9;4?{mUz=Sxqlzu#ZJeA#xyR@OIiV2*dzUykv&+2%pns7;R-da>?}tsizT@_Gm# zcPo3WbDat`CO%ot-w&Iw)mOcK^zx!3UmM>p$2c3$%JTGT**$C3DrNkAV?6t#mrJ-@Bt?=NLZYzOb_m^yX3*^lNM`%NS3hm|#|_jI~U zvxnyNF9TaHlvQ8ZHPg(v^P4`c-=&nz*UF-%WzW7e?A`YM<)SiQhPQIptXd&YN{)>- z-%!SzQ+GhY3m5b3^)D-xRe!aA@r*mt4;{-v)8Ajli+Jc<`GuV}*yFr>{=QL0_}B00 zC(~E6_SxS&y<6p%=rspcF7+={TLzR>KbpC9(QTi1I2@7ZkpJ(ZD9gESTF=s#(iitH zXQuTZ(6n6@A!`>(x`JJWC<+!{xxI(f%H3h5Z3IFWEBwbv%O_rC@%a+3r}+HOBeQZl zmRi`e$t>)6Xz^g8d=JZU*yg7TH@*g>dpr4f4ex|4nt`P|T86OUUBK$Fs15zV`etGE zw}SzeA>8>{9X8DW$I;lGci=F$9sLx;E9*m!Pxt)0Qfar+QBA8WtYAM3N# z5jajgjpHp-tIyig9xSY%R)&VO7_F-Yu+wey%Ls%PaepaVN zEOY>G9mJ5fbvy_xYJrV!<5;-uw|c#{dhK!hV{HyLj@JhpZuQzWV&V4H+y1TG>yx+c z+%oH@H*dGEHeXwRUccOaTbcE#C)jegw6}cS_>ao6-QrfmjFYPTm8|TmJWU#-U zDD2JaPV@D)EvvH~goCC3D}8C{)Z_Il#J)nLv%P0>zGSELB~9T4BU|Lko70y$b7uPj zkS4Jtt0|NBm!P@wW=YTRROxg3Qs>B?F_vpo*+jr5K8P4Uh1J;z_|F7vJSZSZaJ?ey*Oee65tJL#+L z%Ng1+w0mgP(9EHn9fUp+`b%g?SgNp$VLAA|eP39~unJ)hg++wb4T}wH#!;qi*vimp zp*urg4ecD(Gpu#!oX`PbL&HXeZ3!J8IxcKz=(^A;VY9;Khb;+P8MZ!bbJ)(Xexcuo z?hC8K1&X5~sX{V`lWo{!w^^hcB{5M6KGsNFKxzUCXD} z8QH)FkyPVoo7x~L-tLY>M#Uv6 zrYYB>BOCZ{6-CBKvGMUt9^X8^hE-ErjfrbWTjCl<@!-%%ZZ5?!nZ1dH4*83?heWx( zG=^5yvD-;>i@Q*D{1^8kBckn(vS%bJb{--EMGE#i3|AC|o^k=x2L$y{M z6C2m0VME?2%&eIz-pR){w5k}&sI{H)h(BbwxEK}Fgd1MWy;ftUh-exSMVGl=S&LUP z`4dfIXq&AE3TZ9xP>IvD{jVY0)^+CbG++wRl^*S7UA3MfE(3oIb>GIh3)ZV|l1;q}|#|Y@VflZ(nSD zWP^sba+tC)HP&j>gopCjthv<}$;DDeutr7O0%n=Cu%<@GS)163SmI=B+2+@P?Io(N zf4;G`BH|EZB5EWyiq_fst68_PbuGGVOk9f?Hl^rtb#0rCF2@U}QH+0RlbDEj|C)&9HKjJP ze;nFQxA>Q~G_TEzh-@|yF?>?2tWn};B+hE9Q9IT?Rxx%x+SITN?ba%X*^4?W?gG!R1H2^elrKZ<7%?HDYyHfW_!JkE&0ZYn}3s< z(UCk`)4I=^#M;iH;{4gfRpbAJ^TDkZ)x_3;-`<8_Ka$nTKfLywN9Z$8(v2gV#@7EW zU5^LrTc&aC`cbwB>NaZ_%O!m~L=*XV20}~rqO*MKe208L_%eo+4v7ir$&NjruZph~ zXAQG`>$z@p)t4!xOh{}C8}@?)P#0 z&r7gtPDvpp=p75B5`(Wi{v(iGtEvhk;a9jx+itR_{+SVOrsw)3Bi!U<{98u&{+RcNIQjcrXQV9OXI#(ZYu-r8Z}aF{ z?}bMGr)?y@(y#OoX6+AWc*E#;p69~jfZTD?F_!ho&cian{g4DKI0X5>#@KPz%IJ#! zcLGgSz5r*2l3;aM&{h9)5Yl2RvpON;|+1Tg9EA#3O z^j{4R96vDcEz`hq%UfH6mH*u`+m3BqZytf`l|jEn;4qseu*{vWx2=11+q~`+|L(A0 z_5E30e>T3`c1zo5)+=+rdb|@Accp zv-Ce*rvJ3f|K0U_{V-c_i1OdF@vfVDeYEA^ZMU}0?elHZSbuD}`R~wTI}X?}hC|;U zo|$9EjVxea-s~c4cCfo8IUyI=y&{{Z9dq+SJ_v{WPyh--A-ER`!+lT$ib63c4kf^j zXLfwD@5ZIUuBVlSa!?*BfL%MY>t=S%>_M>a!ge9K3fQrn*X;SPpH;^ZPy=d0Er^8L zPzUNl6xg+m`Vb8bAO>Q=t_d`P#$ey+{gW>QvjDV3a z3Z8(`@Fa|Zu`mwC!vvTJli(?s3{S%pcm}4zG?)(0!VGv0X2L9(4Rc^FJP-5W1(**D zU?IE+i(oOl1TVu9cm-aCrLYW^!wPr}R>JGB3f_R#um;w`I#>^H!UlK?Hp1Jm3EqLt zum!flyRZ%3gYB>bcEbCx3qF9|@FDDhk68oy zxCyu5Ht;|&elTG_vf#H5_OpkK`jJG=T=(S8lQ&;@{sILH-COv+B1MZ8FL8g#Ql-n3 zEmyum#Rn=qSoxtURjWN*J)%a=?bHLyaW#aAHtdCZ^^%Er;X^f^%R}{ zpWwH~{Y&C@*e$-78G(bmes}|HncMQt{o9Ctoc7jj-woFNH5l^SC`$ZQUGB8D9XQjE za?<|fpVjp*(}pH)kAZb~`D7$)do^2F`nNth)3SWL80jC;`RC8tW1|I5>s5sRab16y zw%UK8Z-1EfcGw8oX#~b!^^Fg1z_eTlxI_Huvi48&`?P&qq&hhWoLnGJWt z>(`y?v2oq$-1I-G$D3{x6FmW=;Yk<+V__VOhY2td?w)u2|M0wn4=t}G!Z z-qDV9d*}cip%Zk5N1+RJg>KLtdVrl|^n%{d2l_%k=nn&6APj=RU(Eb{=Wxu3p%+ z2QTc}gyBUy5}mvZ_Rev=qOK(Dnuiy5Eyk{Scwy(h?!0=Fck6TKW#`Ox{_KV2-MV`O zx&m{yaaa36P$9pPUA&oFM&rmY5Shw zMHerD061F)qNoVZ9MZ9DSfAuoa5 z^=;dW7jD|N3oq<@j~8yaJH9(F`_ANrefRRh)~6S48{Bp7)@k3t-1XrOv+rA`L`bMJ*+Q}x0=-(I-; zu-;xFw(G85^z#z}**jc$H%tKhnwD{yD+PyUWeSb@T2r zxBap^o$Zg^ysZOkv%B1EdvM3GYjAGf+U}0;9(QUm%!_~L806M_r(=@aKWnQOf9DwF zu7if&g!u0qcWgO$;eM9f<62EdaNBKpw@-n~+RMA+*z!yOFKqoLc$t8-Z6oe58`o{8 z<=yq;9;4j-<-c>h>O$RK-0Aq`em>pL^WQmMx%>Y<-i)yO+3W9=+y27~_q&6;uXB%q z9T?edx8>bFS>3_%Zdn537+wq|k>F(l(zXwBhuOGpJ1y_7AIrPTAaMU``_lyQ!p3*^ zbJn*6Zy`u;JDhFKi!};AOCV&fNT8t*4p+;|J#L_~O=Q+m4%e z_f_s^A#m9RE;p;!=4H#-3#+>W*mCy5+rK7w1=!nm-7>2yaGq9I;C%n?cgY7fizWmkjzxr(a)%1V2KQ^A*E?X~d{;!7HIgLBMEmJrDSKH=a4YzI2tuJt& z^;g4dGX3A#W^7;O&d2suZvH;WIQ+jk?N#qyhx@zfJB{b|#Z8y+W`^Bzx4&-M z#&@T2hZT3~vg3vqCA|c;bg;Zz7VeCn5ReX*cgx)CnC`X6{M2K3QOZkTyLRMWKeDtt zuBF}K;pG2r*tTfD#qz?=XKg>{g?;92dv?!r?ei5AP}YvTwYdX$;gz}d+5Eh)acvrR zU3g{oneyUMFM;iI9=c6H`u>0tT5vO&%? zfoXSK8x~lnTjq{y=^;+NfoXSK8x~lvyC1Uspcn3E&D{^!vE+VlB&FSBiZ?v4%-!Ex zI@oZx%$mD&E*3$Lu4SAe~; z@=lp88(SXkvaoj8`K=A}!du>f$26NZa6I?(Z*|!^cBiwttlawHg)Jv5^P&z3H*d?$ z&0C#r-qP+lfb}(SeYT~{3v08xuI+el%e1IB0=6<+rh#SUf|S`Z4IIyo9f4&PgOu5E zByhY+LCPKsQf6%~eTVX3{jsuOeX{ak{j&04eY5gl{j>65eYEmm{j~C6eYNsn{k68= zslS2CFjzl>^)Xogg7qy}zk>BCSbu``#rk-szSyw9{#aSCK3RFNepz|2zFB#&{#kjj zK3aLOep-33zFK*({svojHf~Aq!p3p))-N}2{c-cw4>xb^ck|Y6H*f8A^VUu`Z|$*l z5?B`4PRj?j)ye|fYh{6Lwz9x>TUlV+tt_zpRuYb_r6}HAtC#R|%Z9dyujoLCWl$EO6RhLCSguDeDuYtZ$IA zenHCm2Pqp6q-AINOaE#k~an z?@rq~@WQ^U8t(T{O9#ulW#NqDg$M<06c8m{JZpZmx<#wzO zR&K}pVC8nq4_0o+{lIc-W8nI<{#tpk{#tpk{#v;ato~sAwQ+;>*UE$S*UE$S*UE$S z*UE$S*V+=Szg8Zszg8ZszgBMZ2<)$w8^Owh_1DG?)?X_R)?X_R)?X_R)?b@vV1Mmg zsv+3^+zUHjbMto0Z{iKacHU>h`#ELynX}`L7kxI_zHZFR4|SXAHjNk7e>ZRSyLn5yd0VD# z-s*Sr-uP`Ox6hLo-gJTGHhy54S7%_kTep2Cy>RPx%e}hYGPiEG+{P^h{k=-DTNc=s zz|WP{8(7vLNSUqY!13&}X4|i=J1^X_z;*>27T7-9&fUJ)dUo@+p546l)y>=V?q}Yn zck?#Ao44uRye$tmZ_C2XTm5$4>V?(s=B<7=Z}q!*tKZFA{chftXGyT>%wE`jqpz32 zw(S^RSlV3=HObrZxB0oBb1S#~qFc93=kAwmT@M8>x{$DTd10S-+ZMd&O2U?d7xhUP zURc`t>4mjvfS1AcIk*0LVR^Sc%Uhe>epuNM@WQ5V?`5#%tz9;r7glEVxMkK4>yH<< zer?&7q{B{x;r=$GrqD=%fof zY4@I!yDaZ_#tFPXP1;Efy+5*J3sWIf|tM*o%91v+Rib(u=7eU-0i~MUflKL zu9IrsgxKAVsypQoPTJj1+P>6_T3!O%^&>B8dkJj&RWICqPLx-O?YfW`w%_z3+Dl+} z9~9%1$2w`-H+j*>OJH|@W&0;D?3~SuCSC%&$3FKs)!Z4Ug_CaSq+2;@ciVr&DYxUl z7w-Nb!7Ie>vB%wic5ueAW0)6q9oGxnH+tb7Ke~8@*xjFYbIR>F<%PQ+?&%fcUQXJM zEnf8T64*U%yT=FHPkZ6+uk9Sd3-|aj*ek^DvClnLyXWxker~ukt-H?~;gsLq&J!2L zKi$snZl8(E?VoO+cel6yJ=@#=U-yA`x3T{{+t~kwW3Ics-Rb<$JrBIo`QAT0ulw&l zm;0y3IQP8kpRV^ionQTLIHz*g@7?bLiTjqn^IhPdZa;U=;S-nbowm1s`hD|G`D>74wbR7qe0O`hyS?4rza?%1|C_I|-|77P?*1)t-QDTl(B1vp-Tm9${oCFB+kfRd z=0CkgdUt#K-@m<;PHdw8-~Y+qjoh7Y;({;hEdO#&`akvioc~wL*}4)2DIg7`hb)jC zazS3W7fOKj`vI`u64~#A>^i^wj>oQ{+CInjBlf!(JGZglve>zdU9Yx#sCMtde(zzw z;jrIj*l#UH!ILl!Cc2xr4{yOH*aF*N2ke3mVJ{qj zL+}Y4htJ>?oPl%jHC%-6;0pW**Wm`-hR_h+2L~x2HKc=#kOi_sF31DnPzZ`ZaVQC8 zpgcSPm7ywBhni3uq97V#p)oXp7SI~nLVM^0U7$Pkg1#^S2E#CT97e&DFdm+QDKHIY zz$};xFTg@r46nd)cpcWjdUy*q!4}vCJ75=l2z%im9Dz^a6r6?g@C{soEASIs2YcBl zuMY4fffSGiGC&r{4!Ix?ghL^?4~juaC<_&!5J;mCtwVWhe_}>OobUR3+BQLun-o*5?Bf=;B{CH>tF-C4V&Rz*a08FM{p31 zz;XBtPQ#b*HC%-6;0pW**Wg#U4WWDplR^qe4e1~wWP$9E3-UlX6okT16iPs8C=ZpO zDnvje)P-nh2=UMyT0;VKgf7q>dP6@L1jAq?JPG6BDR>5+g<0@CEP%!E3M_}$VGX?oPl%jHC%*C@I73GpWzp{1tCfK>_Boz1!*AzWQOdJ3-UlX z6omVr1eAiZP!S%2Y7haDP#2=1A;d#7XaTL@5oik?;8ExSePIwh1|#4}m;g_~6qp7x zU>3}U7hoYQh9$5JUV~Mz2G+w{uo+T0!9h3-N8wXA38&#Kd<7TaTeu8Az)x@; z>?NJaAsu9e+)xmTK^dq74?}He0F9vuw176y9y&o+=mi5{2s{QOVGN9iN$@mGg=b+F z%!7rn7+!%Duo~9GTksBSgB`F7K7_q+5RSm7@Hw1;^Y9H^g74uf{0zUqO$bTOX97|} zTF3<1AvffQ!cZJaLj|Y|4?|6;1N9*m;-DF{g0|2RxtQ2of$i`C?1hivD0~KAz*q1s`~cU%-u|1ElaJJp5wb%bCV6nGY9!wawoUV#N0xB(%l_*g+| z$N*U(7vzINP!vi+Ij96xp$61}XlMjYp%o-RC+G&fVE_z;5%2_zf$=a2o`$LLEX;&C zFb@{MB6tOs!zx$<>tPdYgI%x}4#9Ca1?S)*T!CwF3zDQ}e+n5O8{~!pPy|Xsd8iE4 zp*BQAV`vU-pd)mH-q0Tg!*Cb{V_*VIhN&cpcWjoA5Slf%o8j_z?EP zVK@$-!x{JrzJc%H2lyF&h1(FuiF5DbOkFcL|MqI0a|m9DEHI;XAkjKf*Qm6>dQYUz(FZa!3VfAp>NFY>*RjLp~?~_d*dU z4ke)sl!phPGE{}?P!noH6huQTG=?V799lseXa^nPQRoIep%3(jK`<1C!$=qnV_^b3 z1yf)e%z#-i7hZscuo#xWQdj}6!)jOu8{lo&4DZ5rcprAdN3b70h9htcPQd5z1$+tT z;TyOF-@{e-8GeDAU@uhm+yi+bKNN!dpcvc_rJ)>Dga@GtJPb7; z66!*Ih=E2B56z$@JOT;O0Xjoh=mEW<9}I*c@EDAMCtwVWhe_}>OoeA*Cd`3(umBdp z%kU~Jhn4UKtc5pWBfJA!;XT+1AHW{i2M6IW9EDHeB%Fq`@D*HuZ{afh06)QXxB<5z zG$WsXNCBxK9b|+okR5VC9tekmP#B6r2`B|+p#oHbhoBlnKrN^P^`HSXgg9slEub~D zh4#=1x!suEDQx3qmsS`G@3?3erLb$PC#a zC*+2FPyp_QB2XMkLK!Fz4?tz83e}+|)P^XChFE9}O`tinf;P|&I>MvS4SGT!=nsQn zC=7>@FdD|f1b7Ojz%-ZvvtTZ~01II;EPF z;24~M&*2OB63)Xna0$MLtMD`Y0yn{zna@8YgOrd4(nBW53OV2&$P4+Q5ZnjF;C?6# z<)9)w2vy)=r~#2s7wSU{G=g|&1})(cNPrH|8M;Cb=nef~APj-WU<5n?V_-Z?f~R3B zJPR{n4$OlEun1m;S7AA2Th>`w1&3O9y&o6=nlQ0FARXeFbp1tQSc;;gNZO1o`LD`9L$F2VLrSFFTpFY z3|@m(um;w{Td)bXz&6+cyWm6E3kTp3d;-VeGdKlj;2eAn7vVd&0zbkv_!VwJNLD`o zkQ`D$TF3yIAsgg`+>j3nz`aleibF{#1LffXs0>x1I@E;P5Czc?3yq-(G>2Bu2HHVK zcoe!pPv`^vVGs<3;V=?L!&sOAPr($J1~Xt5%!L#!Qu!3KC6Hp9EH z9o~oC@Dc2XkKqU$gA?#Md;wp=dH4n{!S`?#euiJ*Cit@P`G;hX64F3=$OKs-2iyaB zAwLv?`=A)y52c|TRD=hi3Oo!oAQI|AeTacZ5D(3uB|HKN&;dF_SLgw~p&tx{A@CTC zfG1!KjE70^G)#qOVJ6Ihd9VN$!OQR}EQgiw2CRiQVI#Z)Tj4#}2_L{7*arvUFdT(X z;Ut`fv+xyMfN$Y4`~W|}b+`cwS*#XI6Xjbjzb3Dg*U1~?w`IG>V)0I*e4FK+vfW>? z_&ibmdn=YKYxe?(a}vo+3smrY?9xRH_LXv!(yxauDngQdm$FvBQWV@$jkxWi5r;zP_mqjW$wVXyyC#RR~zL-TuIg@Pn$}FezBolw41?dzTi`asxR=j+Gn9jpaBwUbcIm7ER@5a&x(b+){2Ox0damsYP44 zo7`Qt`==KDxfV<1W%6=)h5VYlQhr@tEw7Q+%IoBf^4qfAC$@M;-YjpCx5{=e*1k+aG<w7r1m9xn?=7m^FhMdT9l z{c=gUlw4XaBbSrQ%MZ$ta&5VeTvv{gh#V@1 z$w}m-axyu&oI*}1r;=04Y2>tWIyt?ZLCz>=k~7O$>@FBg;x$q8~hxxL&$?kIPXJIjyCUF5EEH@UmqL+&Z}l6%X29w-lz z2g^g`q4F^KF?qQBxI980DUXt$kVnf;%46iQ@;G_CJVBl)Pm-UKC(BREQ{-plsq!>= zy8Ns>Lw-)4DbJE;%X8$p^7HaM`2~5tyg*(kzbG$~7t1fnFUw2hSL9darSdX)xx7Mt zOn%#j@(c2Od4ar8eoA+MI#$ZO?w@_PAAd4v3xyitBz-Xy;xZn+vNA; z?eY$Jr~JOWOa4IKEq^HQkw236%KPN~@&Wmv{IPsUJ}e)RKar2h$K>Pkr}7E;GuiiR z;^!em4wb{?ByuvjsO-C?>Euv3Oim&vm6OTIsxI z%kgp(xvAVtZXvgnTgk2EwsL~pPHr!EkUPqqDN- zxqw_yE+pS87nbjni^xUgVsdf0gnYkTQZ6NzmdnUx<#KX)xq@6#en74yKPXq0ACjxc zRpn~(!*X>wLarg#lxxY6a&5VeTvv{g>&f-yXt{wLBge`O)emsKDmfoR4yhLmrKa^%O&Mf za%s7YTvje8mzOKZ73BxyO7eqpW%(hwid&SKGD7l_o zUyha=$T4!P+)!>LHkXy>FdavQm=oFKQ8+shr~j&ditv;3&s zMeZthle^135?Mvi!6>MSez}Do>NA%g@R)@+^6_JV%}@KQGUd=gSM^ zMe@t?5_ze-OkOUpkXOpD%d6x!Zz9fGqUzWd@ugE{hSLGk&pX8tAYw~sZ7x`ED zhI~`LCEu2Phjm<*L*+0ziJVkUE~k)F%BkeEaymJ^oI%bgXOc6^S>$YTb~%TfQ_dyd zBj=X$%K7AQIlo*$E+`k0@0AP7_sK=%qH;00xLiWMUoI(^l1s~FO)+)eH-_mF$az2x39{D4Aue?v*FCUN(${)*z5QNM%9rHt1ygWgkC{L1~k|)bg%TwfMya5ldsFa$iK=r z`L^soM)6M);88LDXSt=q_6P<3Jl+13+LsCVQ#JduDqjw;XS?NwybuodQzg4?UKomi z-O4TjCBbfE+pXR5P!TGDJp--^RDrcEN7g1AAdV9E3w~1dhUSH~}Z&6np_^ z;T)WY3vdxG!DYAtSK%kP2EV`!xCK5wj`obYB#;bJKq^QB=^z7Sf-H~?azHM~4S69P z3P2$!3`L+Alz@^@8p=X>s0fvyGE{+TP#tPOEvOB3p&mp-3^ats5D!hEIkbe<&;}Bq zJ#>W5&;`0d59kGbpdSo?K`;b{!EhJ>qhK_QfpIVaCc$Kw0#ji+%z&9N8|K11m=6nK z5xfLT;8j=#D_|w8g4M7V*24za2%BItY=v#G9d^Pl*bRGNFYJeda0rgTQ8*4K;3S-a zFW@YkgY$3!F2W_a3|HVP`~=tF7q|hpz!%E@kOY!}J#Q}+*faOifjxIG6WFu&vOx~8 z=kMi)ybulrpb!*>B4E$rD*^UAzS2+@%0oq{1eKu*RDrcEN7g1AAdV9E3w~ z1dhUSH~}Z&6np_^;T)WY3vdxG!DYAtSK%kP2EV`!xCOp2);}bHWRL<z*Nl!Vey7Rp0Ks05Xv3RHvYPy=c~ZKwf(0?8l+q=Gb%4l+O{ z$O73Q2jqg>kQc(C02G44Py~uW2`CArp)8b#ickqELlvk7)u9H|g4$3Q>OnNbKtpH@ z@z4~SLrZ84Z6E>KLr3TgU7#EEfL_oC`oRDg1VdmL42Kag3P!^i7zYzz5=@3EFcqf5 z444VCVJ^&r`LGZc!Ar0NUWH|_0#?E*SPg4oJ#2uDun9K9R@esHVJGZ@-LMDt!hSdi zhu{bth2wAnPQoep0?xuYI1d-#B3y#Ya0RZyPjC%>fg5lOd`VgVV9$$81}VUv8JPys zfju`e6J&vGkOS=bk+~r+ghK%+1cjjp6oV2_5=w(TQ?fi%gi25usz5cU4mF?_)CPOb zWIc$67-$HMAs(7Sb7%>zp$#NJd*}$Ap$l|_9?%Q=KtC7&gJ1{@gW)g&M!{$p1LI%< zOoGWU1*XDum;p0kHq3>2Fdr7eB6tawz^kwfR=`SF1*>5#tcMM-5jMeQ*b3WVJM4sA zup9QkUf2%@;Sd~wqi`Hfz)3g-U%**72j}4eT!c$-8Lq%p_zAATFK`2HfiD^BACf>a zNCBxJ4cK!rGe9QD0@)x3OnNbKtpH@@z4~SLrZ84_6*JhXb&BsGjxG&&;xowALs`IU=Y~zIfwm! z?0tV&T-CYtflOc$F`^PB7VQ{Osl|vXDq6IYNGw`ZRJ5pQNCHZfB$!MrS~R0YFZH6O z7QJYx7cE+hsAEbkTC`|U(W1p%RJ534M2nVMRJ0^w@~w5w?Cke!k1=}vp6~l(_VcWq zS!b>H-Fv_1$DBDcoB%bz)j$}y7N`ZT2kL+ufO_C2paHlUXasHrnt1-J`n z1?~abfb~E-@Bk12HUJ&K!$2qSD9{Bw4s-)g0zJUfKriqd&?z``>$;{hL#0QiBKKoT$uNCx=4 z&=g=FAQjjT;Il&y00O{VARXXyL^FWHfJ|T>z-Nli2eN^qfgFI(7tIAu0D{0mAP+bR z$OldV3V_pqLf}lG2sj5Q2F?RYfD3_AU@1@rTm)1AmjIQ(N}vi@4TONpfokANpa!@a z2m{vwwZQd29dH9s58MPa05=1Tz^ylz zFb;eGOaLDPlfYJB3fKnl1Ajc=0}=o~FcU}uW&z2-UO)=450DD%2c!W900CewkPaLI zWB`W&nE;=^ngz@UvVo(49N;)07dQb30tpbA(Ggn-L|YT!zs2Dlms1J?qz!1X{Ka05^e+ypcLHv^5p ztw0lSJJ1Z=0ki;j0jMj8i~w%~qrkhs81No24txMi03QRBz*b-i*alcLu>Aoa zkO26BnE;K9@EX*bhhp4gmO!+POeFa0rkA@OibFz&s!em=EyTwMPRv zz;Qq>z~|TofrUUGa1y|0+MWUw0H*a z;ky@*0_+2%0(_ot8gKv*0OkUGw(lW825=aV3Gg|;S-^ZC8#o%^Gk=c*a)A?oAg~a~ z15N_+fl~lJ3-~mk5I7Sk0?q-7f%AY8;6k7jSPGN@7XcN(B|s&x5~u=J10mpYpc=Rm zr~$49!oamaEpR&F9Utf8oDZA=@Y%_y z0fhjcpVO-7df+CY0k|1x1a1YIfZKs);0~Y#xC>|n?g83>^*}rD01yE-03E=?Kqv4h z&;>jWbOTQUJ;2jIFYp}D2fP6E0~>(>;ALPCcnuf=HUY!HW?%$(8yE%N1;&8)fN|gh zU;_9Um;|;0Q@}QWH~QlNACLg}ftf%OFbhZq_5xCXeE>cmdOsiy;B%q_z+8aOi#`O% z01g8(fq6g{FdxVUjs|i7K1(_mH~|O(3xPb~Bp@F+1tcogUY9tXOCCxIT|X`mN)4(J13 z0Q!NAzyRb0=x~30`CH2zepusjl&5Ae^SvVo(3qXGV3LOH;(zye?)a3YWgECNmfz7OOBCj+Md zKL84VQ-RZf(}6UfsGyA)UklmX?yMZm>C1+W~r z1h^Ea1XchmfmJ{ia2c=~SObKBwZP@TkAQ063gAlM1b}nLrnQ%QMwf?1m#hg)5%R{2ey`#%-MVGuyOy8X7l5ZR2JbiGf+V^J0T@#5|wdDSX^y}I< zyq@)tZCh~0wsrUUAF{S@kK1n^Ht56gzH6u9ZuS8UM4tx=Oi2~p3)jr&b zzcwCstLozUa(%pQu|6t<=l*!xv($%gKVFW5XHy(s) zPewiW>pc5h9~X~X^P^1E8ow7_zUG*IO3!^hJ5Q1C$vAxB150NdUv7$X##3&4?D2df zLb*TAhwooD^X0qt%X&N6@gmoGK77N2G&u6(_;M_oYmUe@7?*(qIX)iu8=sq&j$?UR zGG0FFW3Tt_!8$v|ZA%*h=@_}&cc1JI=w%X%u!jj|fwfXvRRy^0YhkLN(`sQg{ z?K<>gNnVqb;qdO{bHmAdIC=$^k@a!mlw_`t z54UlNdUe^$^mduwvkG^T)VlI)l4@>r+e+1W057%JHd>!+_ zA4m-Qj=~c2Ejq?oUxj7lL4P>oI45r*mh=zjVLj?Rw8&XMg=HiX3HwiS^!fs4ech=J zxBdp*9}fGtY@Zgc=Mv*;#*+DluzWCnL%4l2mfxEh9)Alu>X!Pp}>qkDY##xx}~w zSW<7;>hKOM$p^M=UDva9`?}2S4j+E{lXczT?_tUHlUUMM@a!kpKE80^&s@fb2e^b@ z^a7UHKT5Eque4*z-p{76B%j2x5x(q)u^!8oPU;Ea(nqj-a8|hT(W!M^Sl{?Z@b>B9 zmToL@oOEKz{U`THaBTmKKhb|!IQiKrdw-k6lKIE_rq;C~zU&2uPhiP>xqpFw{j_i^ zm)QOTT;AsoC%s4>7tXYo)50kmow)u@SdV^(v8+S9|8G<4>ai>wo?6#}Whs{IZy3u+ zC4Oq_kr@sj!7_w6-%Rkf8R2>?8Q)Eg?Gf1x%X?G9S-U&yv-btZ z@im4e&%-IH&icGLSkJoe=jer4KIr?eaOnY#UR=QS?ct15=}QfdoW*5Yxbpm{eiijd zxD-qF-#P$(-^_5)OIWU-5$?j0>nC0YZ{ICkwaMXiACXTFkA3X$p`-EsgY$azF<7Eb zy;w4?-{$MXzMO6A9=sgqe=P0wSl;)&!;Qx~{w6HjzlY;C=yj;63dAZ9t3a#*u?oa05UW6}0 z3dAZ9t3a#*u?oa05UW6}03dAZ9t3a#*u?oa05UW6} z03dAZ9t3a#*u?oa05UW6}03dAZ9t3a#*u?oa05UW6}03dAZ9t3a#*u?oa0 z5UW6}03dAZ9t3a#*u?oa05UW6}03dAZ9t3a#*u?oa05UW6}03dAZ9t3a#* zyHJ7f9y2YX7I-!}&U$H&IO{en%lH7pyz}{D*~`J z*ZaN_5*mEgYd`Z@1HcPF_f0-46Icn{0j&Zk0MdZVqnhli3G2yk|E14LzsqNRaHr4e z0xkz?z!w5D@p@LP&+7ZN&w3oo!n=Le^>}>%mYrBm!V?eA))t?26OhvEvvPmsvo>IT z@D87q4Ag+XjP=x>#`-bj$wy2I{7aF8{eKa@?*7@|m+7DWuXFxirT_Uxt-R`Q){*r$ z*D22VtJhy;>DB)iZGYL%SLvVop33oc^?y&N&-yBOyvt{mJnpm30oDVv{@}A}AN5&1 zz(#1fkKs7P@-*N%tfMCTDMSqU$g@7Hwclrj{(>0bh8GY6Y{Ki{MrbeM_yT(2iN|s! z&<1Tk@P6o1Sl)x>e>+YZZ zeVP90|2pUYRr)^~b(eMWs=w6vn)Nr=DbD$;*I#An)&Cc5f7#Dh>7VwZTPzy8x?La>;3QPh1zb04#AP2|;N`WdM3^V|(Ko2koOalI) z1S=KD0)jv>PyvL1CZH1-07ii+AocYGD-&QV#Ih0y1I<7u&v*ejo@G1C>B6&^z!;FU89ERIih(Mi9%u!6fN{Y8CTb7l0EIvZXaYKbeqa(v8%eMVfGVI4 zXa?GWZeSRg0+QdtIDvei0tf?*KpW5r^Z~=b6p-|Gf|U*gfdZfms0UjA$ElfJxadFI z(fE?rPxZ8Ob+7gH$hWhcdo%EV*(w(&T7~B)T3&sH-kM=?{Ja)C2N+qKXpLOz zTmz1jN0*m5OF4|n(nPBh=mQwb+#@RxdvT(b4_*Xteb2N+E9rjJ{14aU^Fh)ba6o&?)Fn4f431Eat=FbP;ECt7|W8At^Jz^>-ZLjOks^MUUG*}zf2(ZDf4 z4sa~+V{FpaxqhqfJ@h|-IaE7y%0ORc>q1RJKqfF+mS{Bt#Xu6!y)4nH0kVLRrHNJ( z(7z8K?wX8y}ouP6ky2`h+_?>BM54Eg6KK{{kwah-= z&*|Fji{`~WAtdUc#=_+n#qx~de^=L#HDddsxM}cw3kT80UGQ>S)f(gbqWu4jmv0dxbh?(#LJVryAAW`jT>PzqE5VW0tM0lI)eU=j$N zl4#`tr9dsv2($tnKo2kgi~tjW?+1xi3Xl$D19?ChPzSUC^mk&}2MhyKKzaduKm||_ zGy$!^B#?G0#tC%d9A}~r^E|FAE3O|)9;XA*CFeVc*Hwt)w*9g-{jy{JvfH>8HTW_$ zm~3PvAk_{yfytgEZ4+avw^qPLc{XjF#NzR0N34# zZ>_xm>$mu<$ChFI(4WWhQ{W}Q9H+|p;`#2JcVC1#E_HJ5kDRlS-^}^?7vww` zV`V+nIM2N}-ns%YoI7)V*>NsNoNm2tO}ALj*+GnNkLmW@pO`V-&dIqy@8=oG+U2=3 z=k5ugpOfSC%DJ<-Gv|T8=Z*98a(>Y^GPgVTPd3(5Zg+d7_{VGiRNLJv=NIiuOzpKV zas93wM|S+zd>k?7t{zA9E-&G`qi(MnTr0c&>Z85fIWODW&38SM*qJ}U0F9DUJ|_4CCtWH#xcJ9hH2J2)jD3qs2pbO#g)sKE}K_gxqQv?RV(L}uUxXU zvfT9SjC+k|XMT5oYc5@0wYYNCvP%~)xhPb=dhzP=(CX#oYj%==bET|isFt4>@_GF& zUAyLr&x?`kzpnn4uf+UTE~#9+Wa+BaA=!ib_1Dl}X!R9#Nq4Es|6PAyw6)xGBl~Lo zUAzK2=ZYoOOI9!2+0G%l z`TQO7tMym3=q!FXM|1VJtfG9`rOx_Y{r7W^@96wa%wKfk4;JfeuKp_4UR)lkT&mU2 zzEbm3%IDTo8H}Z?zZEN%RPB888PRh8G^FVKPCa!&Avd3z;%EB{Rje*wQ?aVD%t+wS zU7nxpuPFb_MQ7!oUXZugz5P~HU$kT=`wDy9<^DWJYwRyo<*P$$SMPNDnQ6Qa2Dqa0 zD_nGD(b;D%RONKfFSKk4cG1PlR;^w6c}K+8I=^UtJ3HY2Z}hiztCo20n9&XQ`TZ#+x{PkWqSFf(7cRh#8EvlP0dGeu7Jt3RL(!QhpSt+7 z$3yvwd1d9xR;^wVD#rm|wTo{`7_&NWtMPx)GCDu>7g}=h#miS-{6ztV{<+74;ZxM< zuZl%nQZ{eJ+E97*;x$#vSMKznP{CL_S7(-`Ho960i|eJkztwBXFLTLXNK`$|<>v*u z`&$!Qf@@Fbs9&@EN{=gFwHK;<`u#!O08mTia4)_3+l9BK9ZAf2DZayCym0zk9jYvw zS9Zn9B`cOMTg-#qaDA4lylTGY^0N`n8quHg;bHNb@?~pRdsNapgX-5?{p?!VUv>F1 zdjo#f_4#X5f9CS@B1C^HSMI`LuIi@ptE)|4v;(!=h5lAmh47gS9~m&o5Vm8e(xZRX zpUSsm|5SonD#I==eaSOzXM10QwI%v_(udXs{!)!|RYpDt{?Ij=kAYuxo#x5-OnTrg zipM1cz(4wx^BFZR!RHHt@BbS|kB|5H3c-(TSN{0;5V-nG8yDyE)q$(e$39voff~V`LZy__f^JV<}ms5%TV776RcmA0p$tS1$ezba4_)5k_79z zr3u#V&rG*I1upBIZXNZkb5Bm@nej%v_5N_Ym4cP&Ko-EUviXjkX=NSq@%G{AGx0sZ z3|pJb_v5>O8CKo9PTjcuQjeQywalDp)$Kmh3NR3@2|PT_*-y!t#|K|G)<1O}ejkF| z;gp%yP_&P%@6NQ6cbjQNd|1NA?ZH+Y7iaGyjPHcM8rc7Oe3uA5zQAu~!c)1|Osfic zO0f(96L>v^v9x2Hoj@yi>J!tgDrn<)U4fkM{5am~hQ@DzxIYvuaK7tHi5^>J@CKk| zVJvLiZ{kkJ_u%NCEeY#+{@^$Ukdxbj`xjd$=4e6p183t`b~(`;A;k8=I|*<%GU$B!lV<0R$nf!31OV{v0Wdy z{}ZY2%4_Z$>eyH3#pF~cA2}QIj7R&}m7Jz0=O51YFxUUT;@M-)cxt~wy?9)x_bpYM zG>>`(;QOlW|JQoeeT90-8mM|@c+{&9$JtkH|3B7?$0Uy}y}$4%bD)m5&(2rvS#Bi= z>O+uoW^_Iusam?7F&3*ptOBtL?0N-)3C?*}o_VVAJsH7u3U)?bXyHPQ>(sf(UXOod zyjsWQuB=z*L+RyjEM!Z?H7VP;aSbFrvDaU|0%NEr>z*CG4*l{Ob{!?;+b)xfk%iy&sV|fZuUq5WIe4Q@@>aegPSd z=UBgg;)%xvGR|I#Z&=m_j?A7ne_qz%M;^P@=JUT5U1KfChIL8#lBLV7xWn*r`Z0$u zuo7k_F7U_Ah@UwvDQ+*{-f<~$v*Y%imKrxFZol}nxVg;!*_MsZ;cV0FN;#kP9qyc& z`8nO;&OM*d4(@zz?%u(j`x@0hcj`RNa+cv8+u-n{??x6M&gl3bL8XrdqAg6w>YCT z{B5A*lhJxu)(l%$^S8h_Bk};2ao~(s_2s)Vxf-v9@uq^S#{Rzvk}mq2D>!}~XU7MH zPQTjzoFTc|z81Fc5#Xw+{8iEYLHTQ<+n;{^=36yYkKn8B`4H& zbuyN!alY(dy$^7EoeBOe^w)qT>(9IyM*q!%Q|}a<`LcHW1?hBaDY$B?zU@oYy;^5} zgMu?(P{cD|-i~X56l;}Ah9&dWVENPy`28@JYP>z*PIK}%MUPkRzc)hI0)4-z|2J69 z{?CNyC*kP+R_~4<+_C@r?RuPKj8B~})bX)M#B)9;3I0cL)j0k>koU2F=VPhHKQ8un z&Oduk_x_l6vl^eX-E)Ng68y)4tL?}5h|oEnUcui4e-^wHOLe>@@1^^rKSS{Mz`q4P zB>YoCryu8e{L41onvIv!!PWM$=Oc9bi;Q~q&eHMp=S0tM+@BAFM9wpP9Qb#@a|J&E zJSg}n;CX_d1D-GVMc{?t90&9L7+f`OpXDa?Qe%1X; zj=u@{$oWpe{_X?k{W`@T2j~4L#X0}{9rrr-wqAtJd!O}o{NC0Z;Jmk|`1|0zccplo z`Y;1O=fiyUJI;Uj`xNMk^ZaoDxO%^f!~4#W;3r4-M>YR^v44IC`U;^lf36tsNznPX z=4_0|PmV3VUvUlRPrrKqxpSd68i2ZX2`s|cAYXIxn|KGvi0bdy9{{lZ8JNa=@ zz8!oycu|zI|0*5?cAIYPg;U>S;6ZTa`zH9O;QXx@`8@Em_ldLe5JJxQOTe8r-C79! zwteHQbfI^qYMtZn68s$Y2Yv(AGhaFQ$#deYYona`&jfecbSnh?dGJZ0ZxZ@Xpg*-= zoK+XqZw5d08*w=2JNX~P@~Q)Lef|Xg1o+CRe-Ql0Z{pblQT{&oE#Rj_c_I$%H^9fE ze1Gs4194Volz#{Orw8iu<;m2+3!?fZ;QP;wvu=&@E5LsTK8Ee0>e+a(o-gawA~^p1 z-?|f=fAdB^{^Z%(0=_ZIp8)n-CoV}J z%80YyXPN)o;M4KPJULjZ@ukmmk1tp7h438@UK`DK5%?3}S4R0&)Q`~Ptq0#TE6%zp zs^0;ACwL~hV1EyRKYwJL6^iOT;0xx%FX~ka?zHLFE6`uejZmxYHOjd^ zl^w19tZ#+j|AK!xctGU8Qs~>D|1<~30}`ov_`m1QmmxU&dpf9f^1_9hv;Q)|sSlp$ z)`tb(18=QwfNzD5{nwv{->u_d?1*y4*Di9$Hwd1A_@9IG5LDxDKFRHG6Z{zX?**?E z_3)qU_NNGb68y8lIc1eUpKo$@bFSBl1V0=8v%%|UX@8H)nD=uelY2vYYeypz>U|ze;fWTLkBLTLq_{cAh&vLvZS&7r6B)!Kvpg zbL&CDsn?gg^+v&|j|tB4O$tsu{bF}~mf-kG-Z~Pz0{gw%o_7hI`8ot=zPd_xz9zvd zk?%I}UYvJSzP!ua{!+o2uW_|oZxNiAuH|d6f5NBo^?*Cg+28sFzYG2s!JCA?IOO(M z2p)ldIe5SDXRLMma|GvjD}LnGLxNLps&?zmf>ZAhob~M#oO<;Y?)VzPsb^oUb@JS6 z+`LS1<_`-_f8$TIpL#@a>V&=2w&%VX2R|`(P z<4(7pc9-VVi+-&+=T{~;^}$xRJ|Q^uw!7VWhv3w+?s4n6f>ZAloc;F*PQCQE?)YlK zsqgm(t&{gWraAKs3r@ZJNw=Q-C(Wr>KdU+88wIEC|Fc_97o7UA;EW#^oO)@WJN}&K zHK*S97dOw^OW!|u9LFCyKi}~B{~7QC!TZ501m|NfY6Zt*7_1g>UOzDYpWrEbCtB4} zz7@P)a6h{CrD#81;(` zzaY=hyp23l^T)`uG-v&S;`0pok7nz7a(h$@PW`fd-1=(4sh>N?t)C}2^|u6P{e+Y{)Uh5r<60mo#uSrD=@gsM}Lvf=V8U!;OhFF z{dWtUT;1R1m!-Cj-)T9`xqsAa_;X%ykB7hMbK0KPB4a+xH)iCkH{v@6bv}j<3C{Rp z@%g+E268{Hhxz%w)aZ|N+=x$Is7y1g)#@dDYWqzZe*dd_JXd@8lZ9UIp{EL+Vvxdkm-Lpd2Yb3iaO#zUQx6MH z{pC@2eCj)zQ!f+Tju)JI$(Z(2FBP16qu|s>{;B=cFMLmP>IwhSoO)1j>iL3GFP+eS z>Xm|1ull!J4+&1a?i07(D!ASMj+?m7`$eJP)C1G8^V`kQvjnG}JyYvEpLApU@tZ?+ zekc_>{rS6VKj%{@IQ80Ox85i?^}^Y1y+m;8L#b|kLU8ISX>L73aOzdxbnA73Q*TUn z>k+}JcOUB32L-3z^KG}@FF5sqd0Njmj-Ru@Uxz*dpE`bqgrD(|BXm6L+buZthAg+< zEI9R1!5KdxICcMg9baaQkN$wr?R>n6Z#Unz&;29K(9=(F`}@Rr|KQPIrs0o>{LdKv z7r~E$pC4h=@se%CcZzuK9~BGqcsSll!Kt?kPCX(x^(s8i$7#;_G9)ZSRb^ZcHCe}ess z5p{mA6*~Q!1ZTdt1*e{Lvd%|6O>pWV!Kv2>PQ6ud>K%epFFHl%kN)Wc*6Qn-GNIF7 zC-_H3eVD&q==690K<6hP7yB!D@`;RMn_=P4UUoEfJ=JT(4;8rcr3O{Jb3K(R^2t9N zP}i$z*d9)EuHQ$DeAa0?KQpHa&he%Tjz9O=(Nz9SBY%eQGd^hW2Jv}rx4Apg+1HaF zUSL^gz(0W1>UbzfR$^;ns6kYEFGvaK?`aPQ7@Q_ERqr zoO)W7TMr0MeN1r1j|)z{0ne~=nzKJO3QoOGaC?4&Q!ifajxQ0MdZXZsZxYyA$noO-d~j4u(K`mo^CM+B$de7QS+i{R8p z1ZVuH;M6m&aK~2)PCfi%x85VTonLS}zu?qMu6D<_2~NE??AH4Pr=EL_TQ3rvdXwPn zzfExJod%!4{TipGSXFpQuI~5z2z(M;-QT(n+=t(LDg8EZKR6CoAjP^DJW1#egR7?A z|M@q;PTSjhT)o5!rPqu1n`fXuhVk+zRqFiGWsJZ3T3rvmzqBJh8Tr)pWS`JE|NiT> zpY<6K{1sz7)KmXM``mfaxw2XDyZDA}C9OAi@(y77Bp zaz=1_Ei?M(`iK!fWbjOp?+V0|t9z3!KOG15f}5S^CaB{p2<|lJ{kBkW_Fp7;I^xe3 z@l0PPbowgv45F5-^|m;L1no&6OEUI728;1#03 z7NOJMA^1h`{|ipA4QZ;!B182=w$P-0_t{{|odL;6V}JDs+ywUGTrde?K^XhpM($b(0>iT|dFO z{VH#B>$QSUA>Vc2VbTAj(3#J7yN*xB@9?IB2cqYH=1={l*6B|d{2=%b29JpReL|;y zK=9+>e+j%z33DV^)n5&` z)11!-^@86G|Bc}NFercC-EM!0;LpN;0l4}+#qm|#qy2w_K7#$7f7zwxQ!n(7*dMsu zp6S2Q@!X!dg3myrycj*x!lZz2NHiGt4(7{O3Xc6kMJUy6)5Y z?EOjbD)?Ul9~S#Z)BSFLhu~rOe+Qn5M5>-G8{Gb+-)heK75`528xTJs=EL#y3B3jS z^WdEbRQUss=y>|`1ZV!%F1J1*ICb9>T5m^w3;P$|26k+}TA@D){W|a==&JwXCv`mg zFBSYH_?LkD#P&;lO8YlMufcqA8rjibnb5aDF9$CY^>2Gx$0y>AqXhBTt#-tB3Z3)o z7o6i85S)6}Gddsj9KoqK2~NFLaJzoJ?)WspspmeYb^bmf&p3YTg?<3$b0hd5LR5WI zpV#r!?py1RC1gG90IQ166skgA$cAIWh zW4r}MeaD1Of7ff;|1F@um_Ot&H!KvpDx%DE!sdvBb*8Q6_r+$*) z%wH%t^>M+e2ma=c4+&1aT5!g<8hlKA{<{bBCoh064tHVKgXiEG7I?d}`3CS@!I>{R zM}I!N2qzkH$Dd+7#dvTW?m&w568N!#zsr2W{}Fgl=t=mK;XI+=wjA{p`~c_$f*%fE zDEK`5$45ni9}m4)aE@O+ql16X`vd6Y#h3u+Po3vZHlCHvflki(kzW9gA@AUqfb-g% z^QFEHTs3~)=Jsee>YqBSx8EHe{xqR;JdJ`sZuqH(aQr*X`JCG%{M3g9PdGSg#e(B| z4*B?;JaxUy@s0~WKJK9h-qP_~JoMnG*5i%w?FPR8JMk7RJfE|_G;pUmpNA*^p*eNmnC6`S z&_6Z*rjeiXv)WOT0hRv+28P_*7H5|{w-QB_RuT0YMtY)Gk6J(AE%{QW4Lf8 zXTLnYml*jNFaI8!zIr3y@F%)I`~B-lef`JyGSOe}`3_h8U262l^?@m!kMVg1uQc+J zt9(B)@-e;?<8hjEJQW!EinrxxESvJrJ+`%vT^d$1^H8^-000w@q`$cM48@%;5b0 zoSn9()r|R&^YdC9o+oh^IRD>g#Tl=jH-WztwAwu8KQ8ib@X#lP{+NeuU;Nqwnr`)a z=*he|j_Mpwj^M0EuHe)Q3|=F)XWQX+BKsfp{!wW78wF?n7QvZ+O7H=X@g_}okGDo} z=BpE&`TPmm|E7`eAK-JK*I^e{=f_mxXMB@i$J^r-d@JJb1aE>*T`ye;Dz>9{e9hh~xD;Kc8iRtMf7I(fSSTXa1!9HK(2>IQ6yzwcddIX~@UR2IhYr zJja+%D!9{9tb3pbz?qlzc?dj1@GkHy!Jh@s1y}WZ6+9^To8WnZ{~bJE@Ylf$1pg;^ zq2T`pFA_W+g(?<&26&0!so6SHz#;(O-$-?-%}aJ^UfzU*Vxw3;k*j zy-w)2c<4<+U+iP`8e+zg4R;ly#u$VvN8-<_o zH)rU0^1j0~r+-**>i%zQo%}WtPyg+LziG^eda@BeDaJSE;mn@Yo;o4S%xmU*O@dGW@B+FCUqu##3kbI|NVk7=O3W zIo}MCKiR`SX!zqZ_4ecTm@7E*O&Yu`NEe&)d&Df!U#iicJ)RxUvUJ|xlMdJYQO_2f znR5lF-Xi#1BR~BeLZ`p(2%VpLli<`x1fS=TZ(Qi~mu2aEIUfFy(CzUGzDE`kM4Q^a ztwN_i`AD6gyvnF=P}KKvb*T-X%9m!u*BiXX$d@nj{f9@sCL_L3_~&@cKVtZk=j-|W z@WANg<#>h8`Id_OL67{|reE+gJp5%sXMXEDdOX}8QUs^oD)>^5e4Rq4KRa9JTkYY` z6FU7>f?w<54+)+Aw4-$X1`mHg==2u|ey4}OQ0Vu2=oLa|zGlJCKL zaQ;64PD`==VDv|S5w6di7QNm#;;p0g{P}skNn9U3>yfWb+x$dDQ#qgwUD4P8@HHw{moU?;}1AJR;&-gie1%aDGww z5O|I72aeVG=+6|K{TB*Oy-0BC)q+#65uEz4;MB(ixAPyT``_DR|0oeU{XK$z!^1x; zbowKr{s(*bCk=n_yLvpC9{zlxGk>e#M|t=oLZ`o5j3?;f?=}3r!k_QqA2$5`!heQ` zf70;h=j!bV$MNel=X}y_#HW8x&+l0yp7jU{o%wnN-{|2V5<2~b zL7ktxP1Nsih$mO|d*35pl@TxJ`-z9Y!SIiY`uO(60HTfOYmTSDs86#IpSnPgpY_NP zobjE4?~DBDPbWm5hnHv_44x!-Huwbki$kN#>@UYg-*Yfr~L~& z{63+d>Y?Weo%xyszsc}Z&&7P4=Il?c!cRRSc!@`Ru@T=P{EY7w{8A&H^Y0Nl{i%!e z{K-4T`wRKF*#1{|2?1eXhi7t_)gY-j=xZF>XU-= z{!=0H@iIm2|LLdbc={^^XTBQ2sSo@>`>9U}PCbnu=I!Quzm*|4^?tz_KPou&oKxNL zLBXjv3C{Qy!KquPx#N=rrydlX@dbiY&pKVl^ZG6w_2S2NRj(qU)1O?Z{p5{ee;{uW z-#@%=>>unuV8jOnr(P&H^JSdj?ypunzm$5D=>I*VzbWuVh|d+*pLs^Ua|CDq=LxSVrAMVorRF}}`KgZ!{oBwd1n2zyOLhL^jd;8M zPUrUTT^1R-Jw6d%2z@qq6=Kx+CoFXOYXvWb|2lBq=Ayp}{CD8|eVd9O5`M-H3(oP4 z8oXE3lm0P7&swJE%lD5lV}B0{{U;dD0`Nv`A~l}&s7rnF4OV!XA1rz{D*^=iSJvh*0}u*f)By}bMQiue^BVm zKP>or@V^1>7x}x_y7P|;?!$xj-vKWYeyiH;&lQ~8qd;)>UnDs7O2PL*{xa0hIUhOi zFJ(FEA#aJ+q13^dhv&;ezRd?!jAW6#t#Uc@uk;jKYt%uW%wgPr$6&L?dR{43*euN^_&m$ z*9e_{{|(yD-}hz+KYt&c3@+b4%Y>it#W(7B{@!-%Mg0H8qQ3^A(_h!9{ro*|ukhP{ zuLAxJ5g)ik`x#&IE6sm``q#rBi2C_^{3>v67B$}q;b(m09vy!>jQQ~6@xQj8zuzwu z`S^SIOe0^~Z*)BKb={{qf4`n2;`#R#<9LXt98Xre_A|cix0?SN#(ww%(ed#5r^AR3 zc4$B2hdMRq-)Gdre`qwG*FzQHa(fg$qWz3-?be*oK6QRh26visJji>SPkPR+rwdL!TX2pyM{w$e2Cow5$4@bTa_4-T zVvXX!4hcR32Trx%sXUOPjoa%W@UxMh{i^yG8U0O&`Wy-W1<*^QevU69{M~b72>Y}Z@_vrzbT<}d?C!wY0mzZ{DRJB>l-y^ z{?z}`ociE^n-}Hk_gCs+F<a$NqW;$oO-3;)LRUmhIMTAufh}oSKF&i_>&BM4)_z$x52ND z_io{5fBk}UJOhGL-|H1!pM#kXod55Y+TTY-ed#ZFUHh4@QE=+jo7{R>aO&-Exb@`C zno}QmQ*-8@5}bO~h}Owl#PKl?<0n_=&y&Dg1-}5iP4F`CcEMMIM+CnLyhHH+1Rn$s zpkMxe?iTP#p>sSF#{Rv(s4wSpfZ(?yUNyD7>y7yZ-q!PFe74~1uf*Wich&KgV*Q5s z!2?)uybpi}z*T*oF#2b{vRB;avr;4fA!B+xcK?ENd~JeLPZ-yJ>REzQKS^-vRf1E$ zLvZT7f>Y0aU*{*k)!?-sxb+@`mwo8g>kU44!mTegc>G6h{V;=Pe5`ejzw+OjbG#!4 zPdBz7xpTkB`Tv~0E9%R9xq>s_$zuN0PZ6B@eS%YO7o7TSqCV7b7o7U5f>VD@aOzix z`cc19aO!soPW>*ysUIWiOFc($>OT^kdbQxx_Z9W0o+>!??+H#lDEJG;@o;51K3`+| z;A6~=^XsUwy(SD^Z~Q)ZQs_g-zXjZnT|k{*`?l)+f#b10(VXK=p3Hd8Bum=8PW}oc-OE;MVK- zpJ>_5iO-p#`MKz?8S~?120x#cf;WM43#$7KPJgnvfBmS@Kl>{X`G3L{(Wc%X!$N1i&4SZjD>(H*F}_}p z{zirWWe+`hH}`zo1b@-P-z9YR-fJ1K`UeGPPeX$5ZNz^A{3Ga9*q_z)>4fkzU-2I9@uZ6J zGk=-T4?@0j@S$kFW5E~f>2uvLs7P_=8xr+lzFMK5VT_l0qtH3N{(W>l>b`w7r=BY~ z^`PL?{i)hdJs>#sR>7%v2~ORbqvOeoaDH`Kigg~wPfiD~@0NlW3%<%@e#u6@bivtw zhT!ZkSMX{h-%r37Kp(;hMQz`p@H2ie%{~4;s;SGS98v1P;lzwhq?9iZ);B7Izn^C2L-2Ie4N&Kf20B9;r$Oa zo+hEwUy`f+%$Iz;=G2G8`Dp{@Paed2=6lqrH{(-{_+G)E@$iodo&8M-&V1Gh?(w7u z-f!gN_MQX1SZwc9;b;Eb1@3(2_O22-xA$e>a(fq?sN=o1ccswTU-I|0pYurWyc)^)A7wPhFsOZtpf@dxtL6I{g`oHRpKh1gD#g5 z8Q);U=auUGqaOZJp|iiR;LKMmIQ2HcskaMGy~BhN=1VTu{Uz9c(2kX8>isQ6=zDqS0iiQrP;mB_Cph&A!KqgY zPQ5|!G>`rog-(Bcg&sfiwF*wX_Y${0EI9S#px)myJo-zzRL9ewDLDJf5}bOG;M9u+ zr(PrYe2@OZLZ?4xrS6~kN(HArA~^L?!B6nWpR!8lV|=#YjL#9AdWqn6|AJGm75rq6 z{_2EIe`vMtpZOXDr(PCv>otO(li^rh)Y5N&GzOCB=n0t^k$)ReBD3N z`F`r*?-Tk84?U?`$1`90)taw0{C0oF{iZD8r`{+y&%Yz^tLHggZRBIUTZI354?TIE z9?#D`^dh1E(nGHn`rRISgU};}&iNE9(8uE+J@k;!|7_@--(*;ipZRL9(VTj{;MB9O zbL+)|Qy*QV$MZiP{q-3BDZ$_H@LSjG{+Pc;@b?Wr^$D^4w|nSmgZlIGclbqjw5k2S zUgT%KLBVGQl-oJq&jo)AdcF8OG9vtpFRRnzXFaO~Ux@h2z}vB2-M>lwsrEBIPmGtm zGhf%2`O<{{^Z>4R!H4h#o62|Gf9ibnpCUN(`EPRTnSxVK{kdCD7u+7-Ep9zuaO!=x zYkf%o`v>O38Swgq-{%d0^DztRdUsOz89(wX9nbM6-=R76);l$)-X%Eo%6r`Uu;A3w zA9U+Yf>R%exb-2ysaJ2%I(h%8diz`yaQOLH&-vN?iTf3oK~Dz{+xni?I`CG(Z>0WL zt^bm`;P+A=(t0O#!Jnr7y4GI;SB?8S_utzve)W6^*00H!PjZKzAN4fBx&Q7DK8E#b zfAjrL`#IlMvA>cRi2a%Q{KC)ucLsPiZuqEt4Zqj<=x-66`AQyj>$QSY&w9+Q=L&9* z?@71bDLD0kUac<)VE@8=cw6`L_TSuRwV&}5f7YDi5A?f2RLU z>-SO@ocm|`u-3VMwhI0(xN7QrTxg8HRdD-egGj9(@1L#D9{@ zpP_Sm?t35&PE+~v_@C(7&AGpvB;uJbC^+-gz|Wt>GT#wKK5m~v;b(la;M7|Lr`|0% z^%{)vjCk^-IA{B`gEyX@Xq}BIaeF=Dk-x&o*Csgo zpAww?uN>9&q24Drb^kkVy;^YU)$h6WI>Ddw7+>YM_A~xr!P)=J_ucwx!KwEP&iK?1 zw4ZvN;M7O|?bas+|EtINO15Y}3Dm-;(jlAq3Hipk9_q;{P;F^zN7^l6`ON^y;$U%X*M6Sg2H;oU$I$Of&^qgrWy~)rQS0;v z1gF2(@7DVSr`|ckt#=Dfy><_`9ufQyqn_-)C0Y9!AJ|iK>gj@09~7MWnBen0@=pq# z@r8T2^A`(FeNu4dPug4isn-d9f=7SNLZ{z9+Z|tGY>$Z8KfdpgFHOXs<)Ie{o&7}w zU+m%U5IX%~V?5nrJk%@q(c@=5LV{Co6MUu7A9eZvTdaeAKm5Tsef+eGc=`wT)&1FA zjK|*IhCZIE{mn-I4}njgGu`$5z7O1K&heToIP<3nz7g@WMLfq75IX(of`17A!Qi~! zP}j@ZLZ?4haOP_?_@wxK(Vhpv5N+!EN7nNY==UQ&A5&82qjn?TyMnX-Gxu}PzvBSS z`T1}1@9y6_PY9jk9S>+f&p#=n`umaK7mW9Z&<{Uwy45gEk2e$CY0mbzM{tg}O>p+# znXdiRy9B2mIauo)Uj@d;+YY>*pub1xYmD(;3;ry0^?O(Pdxf9*C&m6qF1N@1h<^kA zEUZ`CKj{!X9{TIW@y7hgLhnZWp5TSiGARS8G%0u>v_JTUMG$RKF^q(`ze1h&CQSTyK3>=i9?WFBAG454}z3 z>_2;<&UcXE&jeoty+K?Lk+}J_X^JVe!;0%{6NQ(kDaCO z$B;LO`h6GUCHG-H>vtNsYN~!=BVU`~=X&_th0gwl1^?v{D!X%jy9n`bL2t!s^?pAh z{EV+Im>vysKA+SHPQ62L)}vE!>LY?v9~FF!$M{Q5)%`Kvf12j&Jp2Kn)1M{YU+N4$ z^^o}gn{S4GEaK(-bBugFf^+;sg8v5buY-?@_t&Pv>2R?*_39D)kH&bIZ(QgcUr>y{ z*TZj}q4U$9FZ>%l{DGbLe{Adz98ad?qxJMkas;qTsw{{#>J@J{^s9)9aA zcRgi&&hYT38vcHR%Xs_vF!Y8Z-QT%Je(pd1cN3yp#JN6d5q|1v=jnL9AC0e(O93o#D${?jh} zjIS2Q@4N8tzF7M|0$%|>FB+e4sAc^M{Ah7Lo+{Vl<^JKnNb_{~Ra57KOrf*?LW9fy zUx2zVS^d6pZ!60qU#Srv5%bCM@V5#7A`iV&=w}%^$7B9IL9g&rPpQ!JU*-{CBaX+F z&<}^d32|!sWQus^YZ09F?Gc=M=5pO1^=!ef^yq(7^#4=nFTyYXo}ypGGyjm_%s(tR z^>M*(L%x!KxSyv!A$0l+FL95zL~!bD1`k}S{nYa+HRpJW1gHLc5l_8SaOy{heAKf9 zzt5=G@4%NMe+7JM`&5Yjx>!H(si@BUy({$i$SY9~r#a`}KB2#i_~*ehr#boQZ?4ku z9N(ni@4>$XybkL*o|zf=d)Uixe@?{LgxvAnf`0@4C&25Y@$4^mt@iWp=QBTa|9x9mfv1Y|m35`o=}#4WE&Ox9^RZryFI=Pjd|p8%#)pOd{>b=2pi}&JN1G7KGptw2rhrmTqpdD&%Qy&^M0WD{G~>r z)1P&-_P1iZe7>0T`6$ui^B01~{6>VI@ngTx@xMiU3jFGN;g8?}!Ra@jUlu4z#9FpQ z>(BIq=Y#Qj;}!4YbR6)132PmGDz9YSZ!D-+lkq$5)|8z7*&xUkUUTh_8vB|2V!%k&pRbyI1EY zZ@*7-_E(F1@_7iOLZ?5eUHh3oS#at(f>X~Gocg~+|J26?U*$2sCNaM&p+ACr$>M%X zr;)$)emy>(KdQF4-+z0B&heBzp#24eZAn+9~YeZ)xXz% z>Ng8cy{gl#_XkH$07=yQXO0mc5}fs^75uDPJl_qR??3AOb6n`0Zz1a8G-vxy34I~@|I~;t zds^3v{e=WS3;wm>oCf@aMs~KU2R9{6+BGDCc;ppK<4}6P)^(;Ou`& zaO$PK?)WOfsi!~d*0Tkt-YPircL+|s@;M#9juVYGZeP29qn`D`PkpdY$Jcwrml^T? z=e3{lffqFA{@eyX$I0_Yqmhs6bA|sdLubB-=x+n`YvAYa&D8!D7V-2~{YCfB{PluU zuX)j}HwgYGkNyWm|IF7a{LB}8N$2ZFeDWvy`kDS_q0?`@qW!$SONC!u-_oBVbo%oQ z9u(*2zoI|#Z1~jqxm}zO7#|YXzwa3H`#1Q>$j^RNJ@bwJaxgxpIp_b#>w5gww{brJ zy83>e^XUTTpEaxZ|D;XY&+#+~&i$hme)W4%>ce9EGm)QMy}!%`9}zqNJ__#CFU86L zp9HV6`%kfs0#{A#|5IW?Ps0ww@pXb%E`}bR|8B_CAo4xw zk*{Z(&PV^C@q7EqQmywPexy3ln!@+8>~9Escp%Xl!*fE($H4pEOSA^R${Pe~IBw zdRyl|&BHJ6*Pai(3h~(7c0D-X?Bn%#mqRD#8rF+?P~^YDBY(&kPwLJy&e6mpt+%i}+y=JzwbTFXLU^-#Z@u5~0&SzRkVA=Kn*-^L(1R zJ;B1^X74|r8u=I>6yyI#04t)6#}n&UB=XVUCV1R|%8fcjub<4nhiDgm##>|V@nvIt z>V93SN50SeJ%ot2$1gbNTY!A({W6JP#6+7KUm0|#Ip^sD5pT~=aOSHK`Lc}hu|6Hb z&-g}>pS<;-?)eTu=bwf1c(&t(ezK9@&iAT&yi>wYz34r6{wd^F^*qR!{}JFz;C~Kr z>UySB#514&CEed~@E`uK>DD;@V2*z34Ik+KIQ~w-sgF;%^-000H*MEC>suCw=dfeF zs>h(v>FfJuKJ|H;t;^|sH$EX+eRBR`wC0gasFN1#w zA*y~=BA)&#zs|?;Gzd;TJxS}Fe+%ZXwio>cLZ?4@ckM4V_7D0qgiimM;6FCzL;s}E z=^vP-^HU!coOcz=!y+m;84F<2sor$$?7LWXSM*OhBlf?I{_aUC#$>;q43Spx^a@Aj_(I3axiS6$+ z=X@|}^q04no*(y@G5GPAUHf?1=#kGKuk-x_`Wc9CgcBf7NNazqKCzTA|aQwZHb0 z4~zS29AB=Xw+Q|p9{Jmaew&9rD0F+g2k8Fq_V70d{UJkVe3`Moj|o5Z_HXL^oKHBQ zIrZRynp2+?ociQJTIcc7?n|_IMpf^h`RQ7xKO#8u^&ITh^AFLS_a~Z=PdzW2-;adB z)#p>Yf3ZFOV9cNSt3*EfYXyJC!(T6S`UeDm(eP96#CV*B&y&#KfWH?j)bTJZ;_0tD zRL_s~8cNXLmvX#qLZ`ngOZ!=mG5A$I=no&Mb^3b@UMJ4~V;CQ~I{$xa%!m2i<8Cy$hIJRh9RBy3+{+2_z7Z zDB&d-6p+MRAyJUrIu}SFQB)XV1PAo{{ny_6oL!xs_xbvHAm@M9zVEfyUTf{OPl^6|lwRX; z)yPKu>&WR@{j*db_}(c0gAsiZ^lc~79I}3|F1`Q3+dkg zKOd!kbVk-5rGGlYD(|G38C}0m@H+ho{HpY;BD&HqKOsx6-!FKH^s-P<6>@G=Hl|AJ)I<`z}^4{f$h%FsS_7!EcfOVyI!h-i*pq{u@ro$`@WYs6Dp~qTewu zORx4^NBZ!6jUNoEU**N|0cz>9QGU^HS)7%p@w;XJOdnAB*MOO}biO7o$jrGML0qN-0Fk=%k_8TfnqX<2(z{%sMS zK>FLkm;3V6-}~v0`*Z%Cdr!~utG{=RYFwYMM|9f3*LhDCpRWrj7L*HB*Y z2Z$ff2Omkg!2gG@%F-+U4G~uPH$_JaoJ&&le0d&*mogsiZ=Ylt^zr!-$u+zP^Lseh{ki>e@*sRigjN4t5mx;z zZH@V7M|7ose}vZz(Z0d`9~+g|PWnT@70LVcy%OQ829>{4q8tcbp65MA{Tme2P@=|w-RD=S~}cz>PUsv%rQ?5HlwSE`{Y7|Ach)}DSBS9amEJ~re}qMU zaYIH||N6&d`r^bv?HgSGWavw(Ba#;>C-BQ+u={iJV{|RUD*si=5Bj3oJ0+s4{Ffp; zYf$})2OVB-^e44|Lw% z-#-E$u}d%dg9BOls{f@3i+=IuM*5`@e$P=P@PA?dxgnw}|H~1s4{E>aOFo*F|1szz zB0O!OFWmll&pQT{;=jQvcNdLc|^m*v(NTBiD1-=g~ z{Y6;)c|OXo_P-k8Kau`5@C{M=?H|wTQ~IkS{3hwI2A}2AA4Em3fW>dB@BQGnz&h^~ zUJ7p7G9r1u#~%it4E}}3YTv_iZB%)3->(^aVPpO8h;T3YTfwotS%~N=>AVPEK>91A z^q&ULyl6!7toN^}{{27ESl`$Pi#{#FDt}glzd(86FYwdxmt^IAbrAh-aOs~K`M(S7 z{@i>$7|rhwNPijhFn*7N9|6xJgT{9cc+5YKNdC!VwfA_i`x~B&n2Edt>pV*7$ARwy zhx<<&p9z<`?`4R-gLEf@|EN z$ra$Ph<-izr6~W`8}Nb255do;^aGM#f%zhqHK+-#;gtsZfl12=jp^0@!HUQWPa=J3Q2MTjuDGP`2+t+`hC%5o5nbu)5mx>6 zbbMN@{{9GyesP4Ae|v<_qCUlU^fLuxn#UwX)&E}idwd5q4^P&EceJ|SuQ`bRUI@OE zcs|Jo;VZz~KIMLoQt7_}9=CNwa-QhmSBN{wPleCHN0I)A&|hkI@i${QC;8k5lVsPr z;mL12y=gQ2{x0`>%1Zwm((icph-8&7@4vuLeXQBmi|TJVk>3w|TT9YH`&Hiu2!!nU zTXS-xFYgfO8>oLj_+0eE!4q1WP2U%u0)F7T!;@7$e=GQp>{pVvqMr_)3H?%!*Mgr} z-<+)T<(0rK{GPY$>8N9tEc^0hp*P-wE%5d9HRo*u6xTl&7i@pQgy0JMq z*O&i!@HItuzeMBnb>;7CPEPmqhrqXgw8{J(>i@667YsC|<8fIx_Z=qfPyg@W+oujQ z|EK6*1LygDw*AMr^1chc<1Od^kv#Z0_^loEhx;mO|9bc-@cRV#{m;;M)tZxqzWfnv zgkgS_{`qMAs(*(om&~-_qgwM z34gT~^_Ti*D1FBW#}D8Sf?r$MoV5A&Ed|ebX{5=&F-Vwm!TNrt+OPGt5qy3jlc$%1 zmz+Gz_*?Zo)<=0qz*k;geHr?2#_w$MYkcnpKQn{%&&&B+b$ujr3KpVX1b zuV=u;PYtvCpBlfvgLi(cCFQ^UkiW~ChuQb7RsRv-yMN%vpY&rk!oTkvVdJUt-v@nM zUyH@BEB$P6kl(`dz>h3xw)@7yA49%gd;D;lALU;IJ-;I3_bPY{@m#Q-@xxZ|+7q(z z|1|i_<-_beM&+Hfo%PFlIMe~Nl@MBX)*zeJ+{2RenSDTZ~zP)#WcQ4K4Ur!$W zc#e~gYX8H~gZx$gC&90k+0g3AA)4Q}!1qV;=>X{u_2yI_{vUAh z)aG=5{Zo`*<-HI3G5_P@*|mNafuBKM-tXIg26+4LGx?VXUp;z+-Tzg4F97fRHZPBx z4^BP>R(z+}K=Se`aL{Lz{tJd%68$8n@Lk~B+nVjXRQ>%4_z>(Bt!L49gP&sm4gB|C z;Hk}gAKTN1pTc^qW&8bj@F=kKJe4;ST*BX6@%Sw8Bj1D1JwJAX&-eT{0si|G7?S;s z=Dg;M;PLQ7kjGyIPx@eU%KzU4Z(E$L$De>N7}=8Y>t8PBIu^>u9q^aN`*+aaU_W23 z_RzmSf!D$>8ZY73!Pg$ldiMO-G>7p-A5nj_K1PFY_xzyr?*t!Be{H-de=_*Zpueym z%>&PbpVIz=rN2`=#fM5A>ll4#IbrE=7$WML$3V!4#&B^PexAwKOo{LW2t3P)_ ze|^S2CcnmDFFgrfg1sjT!}BoZ~Y4_tx z|K1CZ*Xwf(+>Nu`_bgQZBIrGQ@App(km~y|`1ap4CC4vy__7@RWq$QHn(^p?{>GN9 zzAN&KFEovx_TPT!4}7sHc{f<&@mcU&1ut(X|KGs74;*Iam8$P6;E^+$lY5(7`ld*J ziGCOKquDQ{KMH>zymQs?L?MX6*Q!5}JbD=VvNxNP<$k<=2_6IgtBq>UZ^8KuPG1&o zp2vA0`oE5Cgn!?o?^B|$H#z;`An5sZ*?v6{{06^gGuF4~MDQh)H`?bv8~iN4m#Fhh z$%8*(xHPpm{Yc~83%%)>;ck3r|2FXW_j>yWd>!~I_{;c}Q>&Z7J#(AW{deq#kzc2~ z{mJ+T`j%n)CD*Aw(mw#6JI48A)SqX;L4VhH{Q-RQ1uf=Z7yc`F>k7ADDE*mT$gi1B zA5{5&pOxvO!cU@~rTQEBN6u%zg`d@4={tvjC$V4Hc!Q4x_eA^0so-V&e*G_+-TdXi zcXD5wYHU6?fp?#So#XL^;7gdlDIQ+}9v#_xH-NXXK5YD{@5|r`zjpeF`tvPt&j8rh z_rM0u-)3TOX?~&q9Qvs3@QW}11@I*~-yi6&sJv;-_WdoTe-nJBx3@HYqZcrr{64D5 zSLhSKOQZEa13ZE8ndr-31ito?rsOX4bG5G>+!CelSNeU>bA0-L1wX|1m&ejx)%W?2 zF+Oe1|EKoc2z>|Ni)PC*`fcE=(LaK`{Ra42^a035|0(!h_)GI6`Sl$5ZuCv1H+}%` zKt9;~QT}fty6PL&ihaR+t?=zR5Pao^OrC$V!1`Y>ELrEvI~w`}+nhe8{4>E52->vy z2G1z5zXX1xfA3(Tr{b@E!slN}`kn_U&)0V$jBy|QVErS12lU;)YEI?z2Ji*jh9&xB zy2kfkz;8zO-u2)uV}t!OHu(m4(){M+RA1ju!Q)x4!Tx#%d@{}u2~`~_A&_#5DdZXKTLZ;ylTZf;8D#V^6*f0yy|i{NW7Z!-UY%6ni1nDerJ zU;f{r=b1knPw1l;!9Q;wp32W-z}JTM)813S`6VM#`|m7pygwAdyMBZ{;>V+3`4_Q1 zeSH^#Pv-l<6+fPn=Ar)~uLHk)4*E>|4`IG<0dHNE<^LY|>4;w*1J7kWe#Y1LJoxG- zyu75nuY$)vo7vyv7|7j^li1gP9QcwSdU;0wPXUkX&E)yTk~dzyX?>gu{aN$@@sIR@ zPj;~$@jqQbk&>@v=q3CO6McI&g0F>taFH1QZ2^xO!T5Um)!;4sex3MF`_Zl7frId~ z`SyJeyk-sZc!bOU9`yAIXJ-D0C!t^P%cgWa7Fe&B;a^}IGWod&dO9Ao|2X!~;ph*C zd-|);Hyk`7UGHO;(2kF{ButC7_g&z(B7J2Vc;G$wMLc~0c=%IJ{))d=fG>{p%`$jA z{+fN29{MJ*e(zrERqN++@DzW4QvS5Qb4mXo@z zJ2}%w9|CXtcylsG>7hRj-tbsca;_i$7r@W=?UN+K+<5;F_||oqeSh9L$jcAA`{SDL zw}}z|g1tA~m3J7pXMRg^I0LBiyV_a56P^B|^pl~F#$Hf=)xVR3`Msa9hQ}mlf#2wB zvhy1CuNQm?`48~z{b$in&&KO|@ScBU{;B@}--o@w#q-aD;M-a<{o+aG?;mErud4F@ z3hs{9%l@ZP9{z{0pB@e#i9e;_>z@q1_7?o69={iP{s{iAOTp^j0P7*_|H5DCpgrDR z6F!3UH*#Kgw$FbGHhtQrMcSZU->3hk4Ec=7TTlp^lkK(@29FMO6-;KZKPrm#y=u5$0r}}S%uKS&< zNH6>D>)^{6@1uPF?}Fzp^ZO_1Kf8|a4d5?22D{^d~~UmHpxqKL6?9W0B`H!`92$;OFrtOCgs$ z`2%?Bdfz^c5BMbZNBxOE&j$~%-a~sX2VW8K%PrtO{5S7b`Q-oX8u}m2_npumK;OE{ z)4vB^3;!JH@gv{?^cP#dZkPoFVHVR-+R&LA4&g@otycW-U;4@ ze=n3b3q1AVVXi*%p9Y@r1pXU8zh{F7B7LwMeDlv8KdJtHFjHfHvWG7RPrA|Xr`{%`q*KTKj2fqx8g57&X3P>rSEdzix9mC-Z?sx&liKQEH=6I z4gDJM+DPBO1AO$U!_xKn0C-&FA9(_NSEP@<0KWMHlmmaMy)T1L{?M@GI^UjV{N=h& zL3fS6#)H@5-^8t9?Vkc}TFH6DFqeN0_~doNoPI=kE5M`Rk1)Si6tG9|M`=B3eHEb( z-_~sL2dcjh+{1jH9Q^g7e;PbK@+bZqcmn>H{eAs+Mf0olUxnTu_4fzL@BKB} z-=6`$@;+}L)1Kdfo6t`rFGc?=xU?GmP31%1Z+WBs`wnm`zel6-5&anO$(N!3dw!h@ zKJ$6!k5hX-1itf+etyAa^tXy%pYq4op|9q?XOOR#fb(7+DgWoevHkru@c2WVe?jzn z!F$**4)E=H0vz-?_2<{h@BI;K?~CA_K_3JotdrZfWd8Moz-Ml3NQ-<`i$9cl>Z&@u}g;~_xkcim092H|5t!j|C7)k_-S+U1PxGqFMxLt zFEz!dKac(Cm0{WW*+}MRA~dyE{+6S_bMN3h)vw?CE`t9KYq9f4mA?df_d#L3j7>fQ zzWY0TFU*(U0}k^o|JWw*GUUf$qLcq}@SU5RlFxd41NaU63t@csME*F{_Z{e$v7f7r z!uNv@A>OU-^KY(Fe<9PyAAx==-=nz7_y2kD(XGSWc^Ua%1wVEO@f*s|`0T$De)&B6 zGh2}G+O_l_{m<41>5qiIn#&8QB}QL~zV%$RpDchL{BP>t>ENRy|4}FSZpJ&z{{VPh z7(dp-4)AlV7uBcwzYKmf&vz!k+7BN9-`|#^pZ*1KYgFG~!CTN*jAx^9^FK|%pY$=(zZ&h=p9a5)|55y>{rx&{ANxy1_0hin0I$BRDOs%b0e+^2 z{Na3{AG-MA`$~^LBJB77elh%=M_-{p(VvFig#8ix5ifw3AkTum_cHh{+Ox0KKQ{Rv z@Gd@n_q6zj{O?@N{7oO0+S~61Ul+CiU967~|8WrKN;9Bu;Cn>(tNrwU9{54dzZO{e z`y^|@yFTI9GxT2Y?FZs__UXUgPCR>%FO29G=!M|VVSGOaj{T1}fxnGBlTM)aeiM8q z{*Tb#AAt7|Z;nW`_B;*_{HpP3fw8x(%k-^ZLcc52k3RVq@K*Sx&A0C#;CMf|8voHY z?>|!g2b_gGX8*VP!4tvH{Gut9*VDmG$osLryo*j^zxC%|lHUuV_eJ}C9()Mne}hkd z0eCp)<(8lFb1Z}b?2*yX)t`S6{m{%_zZJaW`C-XTUcP=C+(&w**T&;X@XhrR$qOFu z0f+N8&EJ2C&iIZHo$`l$2>;CWP0k+z9tYll{&%R)e=K+|{)}ThJ`o)J0qWlp@I$+r zlKXvo)`1JylM_jA@)G>o4NZ1`SM_ZN-w^TJmEa|uAL634_FMy=jXb-`*Y`E>eYAIf zkG}(cegndd^pYpLz~lZ;OY-`7*Z)6&cOu`m`}D`LUxxkN_yfWG)@hulicWhD2VeGB z=5Lt_-pc%a!RMb14*aC_^T2D+cfx#~1->Mo*(XoW&G=dMRiK}Yzu(#eUc`C9YS!y>y!)GZ;y80I}^XmWIg=xmrfs6`Ayg#yV;)(^X>a4 z{SD_2qAx+w4Ci~oV@ZGGJCQe@KaK`JvM>9V&p!hk^h=HJd~oWIqW&|$YvISRzBgz_?-^P`>(Tlzi z^cm@|ABVp6KZytO^7J#{J4X#m_Vwd&EqLyY*?Ge^z-!^hD|~x?41Vrx)?OUc$Trxf_-TGL;6b4FX+!P;4zH1tzY{8 z0q~uXJo{js@^abv#F@~8exva|2Rvyu_K(^F?g9sYlkf&`Yb38f1-|aj+4=Mr!FNUa z$erMqBYE~6@U`e?47bhKPr#S$z<(osjQ;%@9OCnYUk5MYyjAn9`kT(B{llHVNA%I) zJ0p9zw3Yn$|Fr%zKJSKpJNE8=e!flw4~Ku3`}(imK>s-pmONMb<v3*fb*NN(>?!O1-=ve<#gZPFRa7)l^pUBomXW0!F$1@=incwKJAZlz-yOrPE2~u=Th)<>>m?_DX#;(WKDB| zh&6fgr3H+aKQ9x%3_w4m= z4RiJV3cQowlfA*W=OyqPUusJ9yTNMD|A5!_(H`Hveb_I*{d}|e)7Aci!8c=1F82A~ z3m(Jy))PMciQuJk_p$Y@^MO`y*l(5pOz;|nq2@#5-41>V;dh76KN9)-%Cr7_3i`*P z_k5t)zSpY!mxAN-{%gQDF7WZX(7yy88|)A4gL}Xw^rz;LZv1}=9=NiJZ`Qc}{wH{R zOSWIU3VuF{Km5l>(bv)cPoRC8kH10Rv9%>(3T!^LQR(;d#1FDJ4h4_reDi#;#&aTg z9P+`|D|i<8?mqTq&yS~p>x|cJq!+)O3m%2Pup6xY*1&}zf7vf~fP;TS?YRyd*1yu< z1m1%^ul-T=e+PW>Ptco$p)bIGkNph~Lw^qcy6L0Pe-3`^)a-oi8L)oeBlPb@@J!BU zCMK@DZ*3wzDC~E%Z$zH+p-3Jd3f}4MTh)Ks#mw)4bl&HG5A;JeW#`{B!NXtj=P9H= z2|U4{Z>vA2fp=}m&WqQ8_i#RVoG))ZIK*G6zB>3?&KuNz<)3{4?ZLj&_}F}&0v&(4 z{FlNzNUyb}^oKSdkbF+%p%0q8qP%Z_Z$;mnrSiZJfsZ{s^T+<*1)0A`{QXPl&k(;F z=JOBWDZ&0?KYa^4?$eCE=cj`ZbblP<<4I`G5#Xz_FAnnc%?3|6CyUQI9o!X-_d4)> z#P6}KTYoo$Z=Zo5pvkrOLa@HKsP;%+oVk?td;hum|1Z#2NBi$r!FS?64D#lO;PI^g z&-nKI8vGQab(YE}|I6S}?4QQ}^uMW{{?E(exvytGd?=AHh$}&f+_i{sT&X0rUGdSN}d0_80UwrorUP4WD2<(KmQ)^LrZU zZ~P(tY~TJ4f*;$|Nh{nGcy0)1n?^t zd;OgH&Y>as$e;8+=pp`1_TWNrI6qSRR)Sa0a+;5En_ zn-9u=4%~{oU+3HN3i#+HnLl#hBJzNE=3{(+4iRp3{vEaNIB*~5r&E0W)4<~=5ohc1 z0`MBv%aI;017D4PvB2Xz_+tFy6mR~iDtJ^I`nsoY2jAF1JfO$dg3pAX_xJeA;I+RW z&fL5HKL~yUe_oKkkBiP>Sql|Ne*6}^6aS0&OYPqSzVe~WUoh_@r1$!T#`ho4^?hN@ zm)7_24)_s%J4*SXza4xV@=I`GGJTTv-f#))gZY}{^M4%rPUQCpu-bDeIK-n1e?j?~kEi|mzZraA zw12b@U@t}d{T=8J?dCjM*ridA0vV2>VC!_ZQ0}e?RmD`(0zx z!hh25-VWZ%c}&+ZSKegs^XvCX&li`YzsCOAR_KRt{-*iX{H#W+#gZSI^Y74im%Y3q{}Jeu3_q-r1BD6hJIUQuML223g>;ugKgl|$kY8)KJEQya1yPT>qU?3_dCIVME=3% z#vhlnp3-;#>iaVOnA`D(-2`3z|B>?3{v(wh{A=*BXJ!7_m%*jA+$Zqm4Ldip$CZBs z^BMdz>fe>vbKyKu^wH4c_<_Tt`B(aPgIiAI-WKvp^D_$^;%P)*0G>_!R+yg;gKwXk z%|{tL;mTpj6Z^XM{}cFR&Z8^7z1Io1WalGa2472jU05&sl5h_8)cL;u_dwq_8sA63 z1MOM-)l1+IpR4x$6`Y<=f#=YU)%Xv$z~CCsX5{rGz8?_yV>EbHRQ{2XJXiYTz!z}- z9nSCPfd_t_?f1*Uy1zP__KH6{z}I5GhVl8R@^gP=N!1ch7*b`5K&yL!^k@a^$q|fbvz8in;G++ND?6Y8xs{Zy~ z=Ic%F=Rp_#8|jNHz5fHeoAn)^=N-_Ed*)xv;-~bd@jo6soA#2;@PV`^?1w6U z74+c)O)j1h{M!7?ei3~=^gG!PHJ&POGx)(s{%!-GjDPhDp8i>|em`0KBYu7I6PbOf z@^(V+X1|9GY<}(lU(NYx(3cj_-!Pv_f8fc;Q-9w^_(9UY9@YO8cntizzpwx6J?z(D zUfcM!AWwoms{DH(lom9n{*C_z-yF^FF!J|p%Fb)w37$Z3+oQhxZ?re+$M1q3;`78W zQ^CuymsP*U>lE+}k2`;l#^Y3Q(=Xs(1hD8I0^c0P$5e&4X8!9p7O=md&q&`_`?o=V zqe#53^cnEy!Lfhgdhjy*ZC$?pJHTN)l>S@bxx{Zg?CFny&!4rQ@tgFkC&2eIzHWZT zCcg&DzjuY#Z(an4cz(7274SCn&4YY-Ge5w3<9s^Ei?@}r*Zujt(jN>y>+)UnGCp!1#D!#m1!TP@aF<{A)?}49V|JYx2%A0l}`pePo{6pnG z3H_D*TipH%Uc`Ev<>R-G#9sO%^tn&@`wg^j1nd1)4n;6pw#654yjfp!)OBgZxnb9&mqjpKTlX8Rjdjw@w^I8zO(~NoQeyl(Tq( z8%Vzv{~K&*?fC|H_vQFgJpVl~7yk11M^yihq0f!ZpPp8F^huNN&|d^6v}JJ&pF@zYP655&C^2@r(HKmw?a2 zURmz@*QN5peMkD+3%(=L=Pm+2L%EZE{`cxUC!9a={$HVo^97C9PH^zA2;T}``$h|u zxc=P-4);sc-XDW6n2z1#+w(a1kslyWJ^nNJCgcg#n><;8AR53v4*t;LRmLZZhdKg$ zZrHEczo&qAVjr*!Y<%W}C(hd^xgUNo`7Ju@*VZHL{RsGG{8xwh^c%pBao#!Bx91}8 zwb--MJpBsrn4e&O`|Dqeg7%&xx~*dfUfbm5qu@~Z0P^p;Bfw__I@9{hy692-~0+3;#oxB4c_r&Q?lI8 z|9^uYLw`F!_0ygM;O|*~$nIN@kN92mW5FT*S>=6oDf_vPhgE;3Lf^GK)8|eCr{{m9 zUjz={S5W>l!FNaXuLoa?T+#0*ioOLL?#~Ec0^ZGdh5h$B@XTqMyf`cm|3v>zlfBvif?u)(g$c6qs4)|#B zJ<)od3BG&2k7tE`3iy21&nQ2iC$gW1`|m36L(q3{fA=KyAG{Wv?(g99MBmnu-jCS; z-gCf+hioR>qg}8fQe`vkwJgC&ce0%?p+B5y* z)JOd1e!l*9lm5kM|C$BPZzul8kIz!@8=P+-_N_gS(f)8BO69GE-W8pfRKe$l`xWS8 z7lU_2`o`zMQ^ylONdwiNTfpCL_5NG%x4@S~{?{LZXFdd-qe4GvP$m)??9f86`lIGE~I_4-F-EU@8i%{Z_W7Qx8T&D1N{%+nVh$3 zk5T>+_$$Y;J|+u89|wM9Q;UlS2OkX%_nAbW3_hI8P7_Hl`TtoaW?K}GITw27-#9o~ z3=ZEfQ2v$Rmyt(@S^k5Qud%R$zNGQYLl6E_rQZyG>$h3F!zJKt_|Mk)_Wqvp@7Nx? z4*HSo?{2)uCSLj`^$j`Gv~iQriOc^|kBeK_pTbHIDhkJNwVUjcpu|B~dJa2I$I{(@sX-UvP) zdE>@wY_c7k#xGIdWnle&-we`=f4&Gl8vl^-2j$%ZzKZ;G-_8S`0;m2j@;?Wjdl3HC zk*@wfgC|7inQwxx?C{@vBK_O(*FGG{zxRM|pP$*+Q@}gnPuSANV=;Ky3)%gzHgNd9 zj{5s}B)>KP-Oz(SSoD7IrF{QE@y%L4+rS~7P2>G9;B}Gw{2I6(weK$QGw6R|yzd9^ zDrNUoehGe!^?Ilu@3+9=JYDqAalW)oV9m~N%KUMkbz{lc$3;u&%@GD*Jd{FtffPWE{|0!^|kFD{#0=)J-;)KNC z;M>6Ga$oUX)?V~j@YUR}-`CS0IEnq%e-B0Ze+K=HUwC;!dwvUk>f8~j{@ToW^w!fd z|N7c<;7{*gRsKZ<5+_8a;CLv-Z#6xB!hKLKAt{OzmokMIlN zCgMkDdHS2+@O=}}hkwjOv6r_8Bu9Y%$bE_JzWvjMeY~UUTMRz=KK!lHKgj0jKsh>8}EZ`{*j~dhjFohZg(x-3s1D{0nNo_3vKrDEhy^(|5Dq zh4VL!|1;2cj>^vCUj$F!KIz#$|LfpC5^vh?@!QaE^!t2HevC=RgWqT#mfY*hpBm{u z>fao2kRNLAH(4)XeX0J_ptnTvNuA&gzt8T=ZUK)!8GFU^<7dD#&*r{^pYN-|H^J{g zeqRrc<=w4d{XU!cP5aM%;8);ZrC0kN2e0LP5H`2*+5nr@&*dH$#7J#NQVDd&++~^wvoK{UZ1=&fA{%`R@mZ^Kp&G&%j$E z{q{L8_KTk00nYpQMDfo?@Fm2btn&2j;Boy;7RDy}HQ*3`q4wSkZaOTB$9@=m zJpM(tFXM;bffq;P{}=G>r)K_@zk}m=^wAeG{-5;m4wQckcrL*mPy6=#`V9EX-zO7) zzYluw|EYb8z~k%L_X5AM1bsH#e}=vW`nXRx`$F?q0q^VMl@w309sJzu*?r35nT!wq z&{@>4`aTQ&tsi=S8u_mW&;DVyUwjul!0&VH-{j`&C*TlItnvC4IDEfI_5T*!%6$Ez z*`;r~2>*H%A2y%*)A%bih6ACW{1E`@n69&MeFqj@G;SRejOa*S=7Jpg2R0+;U9s+d7kiN z;AQw*!hW(F9LIC~8N56yKe-tByT#v^BmXFHI6qN;eh;ID`!pKQw?khP`C}%7L%gKY zw}OK|cr^390=z3ne4?MPi)O>mE3@y>1{p?_`c7n$dzct#AZyg-Ym(;&);Bek6 ze9#>F@BMw^pU*(QlKupJFp2VCkb{ zq09by1suLFrT(_Cp9XzF^(WhC5AkfaAA{cxJ_P&!SzrES@H4lyq~A}Q2cCofyv52t z7~P!p95Cly9pG-=9-|J`E1>n`+Na@F>>L`M$n8z~OtKO8;H(Ywsn_ z)zg0s4)=kT|5flI$eWi%2aos!`aJh-v_6&p?ciPW@lTF$cx)T{>lo5OSO1TNK9l%_ z6+ZpQ9PNMJ#jA?G0Q#|fkMdDZUkg5j`^aZ`TmkQ4|GC2B3&Eq7-WYI{21w{HRumL;l59#`nH18csaEP{J_VX zlb`tVzX-l3ia$8M$b9>FEakrk`cCu%@xS`>Q}87A%h3K?<|B_d-#Ht)(*I-~^6wum zo=EayH|akUeb4S6;AQOJUB3Q9x1%rNpAGu$k>KDzQ+>yS`#7w)#i!rhpV{}SZ$9)h zm!OY&`q|)z82^pJ(7V9lKCH&G3VsavVDkgs0>1e@d~ci$RrJfiyBBBvom;`TMgGKZ zf{W;iaH?9PXc~eNRDO&U(I%^!nb`9&p$Xh2H>&cpBAz&uaR^`HRLw z`47DW{)y~~Y2ZVSLSA`!x&R!$=d1jug7fU}>&P!$1Ru@%e9+^~;0ersL74JC3En^2 zkIq_4|DyW6FG^Ak8}uhyqd?oB4vlZk~Sm&>=6 za`k+tUYGPbpS0(@yK|e0`SrPuvR;>Yop0-{*7>(q>J+tBtn(ur)oO2*ckUrqD%XqE za=tq$l}q(W9i?hb87kFDwZ2Nl$$%2rc$|(Ya6H+liX?t78UD@R!na1E!XOm zYHwxol*Ff6J%3)VquSe(gH|Uum6a>`Law82+T`}6qb=9o-CHXrg=&6Nu0)z#rQAuK zv}IMP-d$7*qt&}g?dx-uUI>#bdAc&Cp*Ab1n6Eax?98>5>OJ{N(n)o>O{D^%UiR2k zEOmC(d9LRxG_0?z=k9#1ZZ9_XmWwg2mwJk|dcLQU)ar$fQg^Y&u;iAUkqeNKE7jvS zxoNrX-uCqkucq$(YD)Hs#uamgd_A9=X1Ovvbr7DS8Lid(Iyx9XO=YR4(p@TQL`(G= z{Ls2Mw{XSWWv#h+t&5hNp35bLVzt;=sxi5_I`hy?_mr;Co9pcEZOeD(3iaM zCpLw`iuGb)GSv>1BG*A*bNOmDKaeYy>(zmzqnhub>3uyt14(b&dBt|7hP=^h8=i(d z-Mxh(^GpZYDm`UDuDx2!!%l6?MIm1uSiUUjEY=t2Yh6iSg<&b`aei061V48b+t<(U z?e49fmG3SUO7(#xUntm%c^ZIrk#hBFv6!O>6|=n5U+lI7D;CY0JN1NQZXw@uqNtU8 zt+p}W-N$%Pe_?)CUwM75zJeR>8EiXk(Siup<}Fzj*FoLMVkV;}UtXm;d-Cgx3*q;r z#d2r8t2QlJO81tZzG#(JPJ4GTU+$}fcS{;x`ayvo)qx(3N^wIU%Q0(9W$~Jt=l+B{W@J-r)?@teNVM!1K*SNdvQxwbqD$hD_d zM;>&h^;1Z$Bw3QHl{Oa(OmVqbg+~@L&xHjrdcNFV)MO;ZvYN5P=kOG|a; zO3542gwCq6sIF{C>aAzjlTB3`qVB9HZY)-7G$vxdFx#Q1c4IG-6?<{ztgI;aq((~~ zBnTWia-_AZ z$5$8TjG~rTd)p~5G@v%*D7mh=MZD40qxIF;h7t4&OCvUS!Q5ph<`$goAC`oN1#7~a zHObOe*305~b62(|3zn>0HTU%Stqq{{>{Tn~`c&?D{?hqNb7!nr(7Ga-zw$$?<}aQ+ zefE@eXxgjo)2AWY+q#Q0hI%=DsF%}*dO3BdmqS)`;!r7180zKBB-d9cZLF21v#m__ zkGb0VQYFXhDR5tn%_U#dKHt~PD@21fpu)zULaw{quV>}rb)hr^1S7OhVinkapUVld zRRMFR81zVrTAF&db}~ry5-GZS>oAqiUg(`v8>lHgDbN$jy_1j(Jh#;flcYVI*HZyi z^QBsmf7|=>Ik>UEB#j}LTfU-o)v7hQg{x1WziP=D>_N6A?EO}oj54`>kP7R?9tvP* za?fZoEamQ8SH4{6E>@FTK36Svw6pJ^qwv2CeeAoXT5tR8*|`o{TkatDM)x!+s55F_ zSH7BSLu|1HYC+T2O-V<;sTso(+}k9X$M&F-&<98)ZKK?) zhe}^v!{4F8_}3=21Nor&*=Ve-qI%GF7$W`O_DS~sc4-zp`GGe6FI}jkThcYirdp`m zS1q-suME$W*9Vba1$R`a5%oy=hG{maKBeAVxmYaJ?1kiWq3Fc58|WIEK@rUZIyt2} zmDCYrx$AYY+?}s>7IS^IVwD_@BYm^f!QM^X$W-k|>TkJHM^AATz-YO8O@nW5%k?hJ zg}PsHkGb{5fd*Kz3CiVCIxkFbD)ykn!2Z4E2C){>RX3@6(_bjPQ0&O}b=Pz5ZN3fz z4oX-p_~s6J-&Y>`{if=m_qAfT_#|X!ow*gDH7b7Su@UAWSLn{w`^pk&T8%cfIrYBQ z)!U6#Fa)^<7xeE%srOdc@AuAuO;GQvws|doP;uN^fD4*Aq^!LXYAF|u0F|*HVSr= z4fl2Qh9Y1jRwiqks>2@blgak#MInY!67tktZ`_vbGQd`8kqByMMftv!i<@#?MZ|-f zA)0_4GK3sIVaT`BvusEoSp~>%Uzdrb4n|NCreT#erU~5{s@B;mPfXX4KkKCvZ_x;Z z&J9)ARP8!L>_u2D>9F+_C7NuQqqh#H%^tFtSuVZn{E#V53|uEoFm0%+MvO_`4VeqG z#hTZHaPKa4mWNJ6?LDPJE+qPYjp@`Ahb{t+9BOpXQiggxd&t+*rX)R;Tv9e>s4+l{*n@IS6J8%Ir)K zU^O&>&1D=A9-wBC(}QXs!(l~f%|G_2vq`y+O|+UX*QgQU?eIW_=7@r;pi)cf z;9RNDUrXeb%Bico++3>^+Y`nL_V2PfCpt1|}f8I?=VD6;4rPiQmG0eT138UFNlUDHy2HForLpok#nRbe0vdp~1@z|5ENtd(N za#iMX?h&oTKQYrK)R#?phD1%%gKK25ys=a@J}vZBra|gx@6!0|pokcGSKN0>jkaqBp%E*=Rs+tvtYNNSyFKW3OictZBq1}d{ zCtuj;3^MJy6smt*=gD7}Z;p4hfwC=bQ)75hYpZHn%rV$tHOW&rJ?Fi@_ylo1>eVD> zq@xgdg>wiYO<2wdSq7JUx+}X@G&gXn3D6KTRMdcCeIx!ecpFfu(wD3ZDrG242l8S< zeBrj&Nz#>UK=n%AD7Q%<=M9D7nCf6zJ{m1*gqy89a^-8z2!!!823TQrv_IQr1RIDo zCILax;nOm4tSj<`)P?Rzg<@M@CmF*dMzmaDnqOWydt0ih?ek{GbUTp~^Z=L2q)@J| z8Pp4>=UXAYsn+lOqB-1`NiYO5*_FOx*-%+2@2#+q(o8anMu2W;Y$HDO?t!#@t^t|< zA1%As-dDvlS>Cu2@yl;7=g`Z0D)QU1$s%R3NToXN^-@mZywy_WpQJ!pbgA4 z27KhDjb;cs4F70jAO-S1kgTa_8JOktHhZ6}FQXYmFKWJgDv>$IinZ#rZYy~XAxaD* z?ig2z+-32jP1m%*5GH$6j>&>dp>rjsR9~Sh5eZ*UianM3fK`_(b{Bh+wmuw*Qg_4+ zY$7BzgUXgfAo_0m()`9_56`V%5Ou`SX6VCL7hLz_!V3wUGK_lv0&vqB% z2Ax03g>y(&p%VoNK}RZRD{%86#?oxzPO35l^cqzTHi}=c5G8(07g5h-2N^@MDZA~~ z@k2X{wX+w)CRgsxu>!E`I0%!&*Isxk=TkMx!kq4IpVY3snBH7i*nZIZoC z{gq1%S39^ree(V~4kpAQ(sm(RQHW*?K_o&ud?c5&J(n_2>F#6o<%%W}q*tIeCcS-i zR4BxhlqGopwPA3&Gt_(5oOFfBGpx@jZ7grC4xY@_&ce3Y6E+EgDvPo$J-gc5TenFo z^h&9wX;u=8p7GL%prkue4NAVyQ|n|%T{4Eim=ffaZx&zyQV7^-pJSUC=r! zFFVgtb&P0|Mnw5u__sPu|C{QPSVlJwlcE#V?lh3a|E@^>Z)Xqy9d+$t0wNLUDkeI6{85HQM!Mn>?>1?|%4K!PG9Wk{EzNZxu|SSs45pfB8`F z;Zi@$gE9o)eRwUST444=yeyHvAzedI+gObKNKZ1e)mXvz z*j|{ut(FyfO*y1kjsdcR2ZXrIelPOAP=uG%WuY5*%!4Vp> z^l}=d4y9%L^9psp4bu&I$lBu}x3RZWsBl1_1l64KX)R(@cSpJHwa%h~S{IrY*~(sj zO^wxhMZ1dW-oY;&4z}#<-keROFeVBs$9sXLO`yDsTJ79C36WPbHQ7*m-2pcD)ZNsM z&IAbJ6qgiv5hBikqlX$2-(F#ryN9weg&gIysB-GMl4r{$t@p0a>9Nhbn>Mv$&U&vG z&n^cKJ}*z^bkaI7=aQA9Cw4I2;q374q@MNufgQ4wS@B}fDF!0toTCVFX5Ikj7_gO9 zuGh?9*2?2GBCzBlFaSm<_7~gDm1Pg6;W_s+p1)G1j_!?xBpua#Ezj5sPQf-6b?u8V@~K3S~6#+&ZG*1EDLc`PpKwd+k6)ME5^pb>I{8=Jdz%% zmA&Qefk|>9lN8Gs?bI4$XROYA)azn@d$Hn0Bm7B-4-R*ZI!J6%iscV)$pJ58fehX; zif0kmoE(hxDuS9>mR`zGRprh{#F@{@ojo<^PSQ(Eg@uPhY+dN3`XfBcj^HP5I-ur2!5wrH7>~ok`S5aUVB^1l2|`=0Oo3N(S03-hE`iR z7}AGh_4?!!rEsHn77NocD8lnJ%nWu*PW%aTsMg|V^X`Up=BDpg8f~ib``W1Xa!{_x zRWukDfW{x~x4T#GbNx!=r(a8ih`lL#<;TP(xVMT5CE>+;w-NKKoydGRxs3()Qe>=0 zi+!+v<+Z7_Pn#iizzrjsE#?e0bd>s;tInbfC?36x;V=+4Mmv+`Dr4QzMA-rk`z^E6 zlGtwQ-xF9@;Y81r9*PL2vRfz4l5_K7d!)05v0qgko+cKIxF6tcPKJl$X_lx4s?d#R zO6QbygnwNqXNH`~nPO9O5QYWkKVe9n?OP-8 zva8Umut5U5EJFHX!WW?ykJkxwzNlhvVuX*Sx`YnqtB|)m%5de z)+n3Qtec#<*O$)Et!iD`x_t2&r?;BD+DKd0x^m^*MXf6vEq%G@aS`+oNx4^P^H;4| zK4eK$uxjp#HA7@sK6g2>OM4e}I)R)+yq>#Y!3vr+1Z7$4+?A_Wv@UBsebo@uB@1}J zWZ{zea}}2}M1uKeEL}R6Sid1!vU*wTiY4=hpsZR#8|O=%z)sa3Gk+3MaI%|u))P)f z&V&3D=R?rFZ^T*Hh;Rf}y$w&M+!hk)VCl~(Hs5hW3VWk8-R(Im&cbIYn|PNpPTUd_ z+^MkhC-va`LGe+rhcyp@P?I0t0n7@bqqN_ZdpWJ!$c}Hez0(?MvH=ucNYUat%fsyB z71a8gk3LUefIXpF7b{)PN|`^&s~~uSveb?ReKELtIJa{?00u9ZlQIf7X%`AMr1*>m zSg5wqGGoxmsG#P_MlhSlzqUiaE_tcVT$JW%wj$v?A3&jm7Le4^qqzYKr8PdF*sQd63lSIzLGEM&>WiLp^pL$#b1?Jm26iKyk#@3 zBo(%7M@BLsRzxO}RtjclJJ3sFh3aYdlICL`Wmb?sWOpY8WX&mUZc}e{J$8R1%(W3B zULKT@<&0`#PDq&zk&=-W?$W4T#EE&92gt)T2`Q{4R^T9ug^Y4j<8Xj&K%$;Bdf`?m zK+;3|vl|a{2dBHW`W3x#8izzYgpOV~)gn}_>x2&Yx8~#0mVh554Vrct+@68f;D|oM zptlMHQu91jQR<3}ADnBi_vR_}nJm=O)wy>%?2DvY$AzU03Z2ZKYAAVoIoE|IlMvO3 z)Y6c&bx)IX&1_G%hKF7eg>DU`4Wb_87%6lI?ote;yYW##t#Hm{d%!gd*A%*YJTv*H z@H%~K{NvN2Bv|3nBm65V4)#tD?xp!QeZA=JHR9(;0q>)EbJ8o{Eg0b@t<=01;ZVY@ z3%J_!mq~W=gCD{oOyL*fcbG!w$Ux3}#A<4w?lJJjC$)5X);p&jB0l8?bs5v)(lHpX z!a8zEr3Uey=}ZH3-P8XPpPPl}y6Z0(6e?6ylO8$Hoy+xi8$T z(eP9(QnhMBRb)eC>%yR51my_EZjkSU2ZSveh`)p*rJX}iNn1@XUW&&1Fd^Lnol-6q zgZWE36|~Xfv_>SWs$J(BzVJo5;gh134#lme#oi0Vq`QLYx_g+Ut zWT}BRxePFyT)aMkxVn?!k~F-6Lok|@dI+MA`atu|D;|jBIra~C6Q=d_1>A$dBJV0x zwcM)soK`JenOk^LTQbe!&}#Erz~}`$ zO)B-^cec;OFVSM>=TL>c^2&`K}3UY1T}Abo>SvP&mcZ!mEyVMk)Y`vYZDk6EWZxxRYGEZXd& zoWdbuwNt@_Udyy5$YX3wLj8kUi}dAa8qW7|@u?q&ca2(@3n3>aTqVd)iVNNy?j<=z z6zJs5A{5;=L;i*%jkKGRb8Qu|8GD=JvCBC-Z?P3FH=;FpllO?T;gOO&M47n0NTBd4 zz1`+p88lQ&B#*t=R*|}Ba~x%5!=wPIJ_XdULE^Iw!-vA-qE(?ZcHGVgRFJvOtb8Bb zZ^NKV1XhhaWH~8AC(N)hY8WALUZKW}n@UN4l#pzxQ`twIyWnuEBruL22^k|fH0w*WhPUdnEISI%;EjO@kji9F7md;es1( zEG>>9!ZMARUQtJu#42$}@qC2q`I%8G!yNE#kaCa8X*neep<3v_lTJ3pXlJ}l`KY#m z$i|3|B(mIkr%9SKYofKsPEp)JRC-=xMTWMRJ8IBkapI~!*j0{!28Tas&0Cv2-!Sv0 z#%lKEvvdkB%{KWie-+Qpzml!&e677yipNELv{OhD;}R$M((|wERTW^2kcP;*L6PHx zCkyf9fh1htkhajik>z2IOkSt%X7N1^G6G0+xbBKTD4B_>bXZFA#35RJ{1U-RAZvTN zye(WhE1Z2o{#Qktk~EA(ItGLL-Pc~57I%Bl;!gFZ)Ss+90E2J(G?SWQ=d|qfbTKY4 z+L~7C7R*@-m(#8^b}(JPISVk1oYCJwQ@Yjs%O^+=+$ePCE5xG ztvk2*guc309NgP)+nzgE-Kbn;EU)juXK94UD!kTQ;h6zZXuURHWbdv!jAAQ zCowyctz+H1Vo#GD#2y+pY3COb#UEnvNOL)B;~@>P&uRa1akS}Z?KMiSE(sU6Wdv>5 z)gCoF)wnE72G&l?bSFCvWA959H=|l8%*~x5Vc$sC3^A1M44V1XSy!s9gar_G3`jmC zpYCMKizZLYO-0s7<&sS^SZfRM7Lc@4^i+x)^cZwPo7q%Hu^|sah9Dp-&zZ)NSsYs* zLB!`4vqG&>#@gPw^$Gnu@$ugj_3 zE+C6^imK^Puj4rGwELGV6@)<OMfD|s2k1nFj`zDb0b4~G)%J032byKQLA zKqTsT&m!JP!c=2 zKD}3JWZWe|M~1^KPKCO?o*tqb*4ypN)K&?CSE_{iPlk{(RaJYnQK0O&@BrUFQ*5nS zL8_z;b7SWAK$BRZw@!`?Uc6z%vJHUhB+leU;c*DvWCl_)D2Udc3I`rC#Y``vPwI|F z6Tg;=6J_{n_%FCR1ov_K*W!OABWzce5g;uflY;XX&V^{#qqR27>T}zm39g2Yd!0S> zlJT&xMYn#sEq0BvRxO*K^R5uqx^>oR1klp`O(RX?Tx_A#)b-Lfy^qz6tDj=u)U#Hs z%&n9bPY1(9AREnGQ=j_?!QeLx#Z$Pj;8E3yBh?QM zgcuk!gyv@w)SJU$Tp55=XxS3xFvo_%DNzdXw5r|0%EYBpe-MPhly+)g4VzzfUOc-D&?3p!62;V^4MYz>rQ(K-C%nqj_tV3mq?$_jB1sZuR1 zPj+tbYB9@FYn)5HLD@?O%z~YbLF&CsH&J-mCI#ER{9)sp`C{kcu9USQS;hoPvl-k97IN<a9`jcwVGp$ zQSCz}V>%IBVWOSw&RGo>?Cj4RZLm2?C8NZkHZwj+ru6A-Si{|L_!C|jsxR5C$i-iOS|lIb}?3H0Hdlo@WVY0u|qh&Pe<&uOUaH|bG9h=oR@?dyTtLVkDC z&f1b^-eqYsBIZprsm!(&L{2(4VG>w&wl(;zik1+%Nzrg`QbpHVIBoneY>p!r>F*P!>#9(0TI~Fc9Y7bB|m60RbV}D z8)tlwzqOI*b2KhfO-$&1EMQ;GL=(v+NM(lR-|}+E16VblXCGqXno9t}Lt?w?ODzbi|3f zlLq+Xz($fk{nV8c_oYsafR`jI%yq>J;}6z>-}w1Q0~3T}9}5;X^IfOkP8i#^?^cv4$fhjn zelyv^?h=?(R!_>qu1<(&O^%+*a zDT}JsIM{*1!do+6{h>gkZQwqtm1Yko2qY{OQ^zyMD@S=qMvIBp5c`luOi4biwb2$Z z%Zh^wrbt1`b~BkdQO_MPSNBOU?0?~a~HH5+TWCdPm02tEr7z zBWuC!v{W0d1!oHIE{@sB!Q_!3;X`@E0F(#B`V{Im9a~iPtrd0D-Gky`2vKRL#lBWC zgN~!jwqXkF19Y@peCzMWYh1eX{Ir=KT&s+#!p+f`YM1Hi52`W6=!;3DlmZzXoAMXi z=aSO(6agd?P7L~Ga{F8o|DoyCR$Gw|Wkf-PBx=SOOz&WB( zz1rrOvD)cQ1%ptRMTdGqJ#OH=t>m>`A1s^JYAS77p4Z40SR`;1%I4qC=h#m%!fDw< zOsX_-_Z3g2io$oo;6{Saw;oe7l6FfS?b$i^;N$s_hySSc(( zMvygZUww8$IUD8F$xC}P$=k3=xq-wiiN3Ls?sLo1OD`q|Bjt>KSnx#pX$ERA!!}(4 zY5SbeutpKv;7tr>JUS0DEyFqUZToPtN_?w1WQUFK;Zsu@%b#^MTPrNm5LM2VPAz|+ zzW?a_Gt8R~?`Vh}56R8OR9T2=q)SImif~mK+23&JOoV2b0>|GpEZg$4{a#;B#kZit zXi~(wyp&L<%iAgzH%mnL)o;sFf~MpSV7P-QSYFFSd03v^j3^#s&UXlpcn`UD+iw15IS5MZ`7k zlc_=I%3+FFGPXWl9ElqhiE)9MGkrMd1+1*Up>%tvvlwAzN6H2#7y&H zt8|jw^0GTE!8>llE+td;6o=0WE$0hLCTw-hlMfb``YjUIQre8zZ!1`1+^2gPF|IKx ze?uUm4PmL=g^wva>=HBfxnP;>s&RVTUjt}o&Y6PEh}Z|&AW1c;!y7g%XqlBG^Ljh-QFXgnOfIN05+}6{KCKKEfDO1q-iWSlwr( z2I(PTuCq^}E8ku!m#u$&a}#R#E~c@AaZc)D;FEmmLi8GQuyVEdEQgP>4IIfRnVW>I z?tfj5aqLUBFe*~1y&%r^UKqy*&IdP`B8IKzu=upI*o)LLZPu0)IP+AbA~`dP_S#_@ zJ!U4NWI(u6A}Y}J1N#yPv2jkXX8}03#pb_;8hjW z8Fx?_WD{%D$8NZdve1^E=E!!aaD~MhBasun81D^B$PyW}Q&A>xIequ{CY&9YvQ)N@ z(PlajzDlVc4B9@NNU<Bas(nySQMLrb;qjQBu3?rBY;*92^1JZJ0); z@+z5059iiNk9jGvzA4`w!il+j#@eZ%2Jt;sXtv^=oDVhI$`UKFW^EeMjWrcTu8l*P zGTb?#R0cnGO2A{d4BVXt)=Ur;eQA^}-e*3dq!VjSG%<9LY#;{<20DT>`sk zL(pCzFM%Pq{>&Xqi#R}X;pwE~L+nI4NLfduhut@9`(A$!!3s7R#48X`pRN>5q&`1f zF6y9O>RiJIO|12)^iz8zB4xsc&x>TOwc#HWiKKnTpQYGcQ$H^nQi^f%Gkg!Gu`ZmF zOdg5M%m_b%0QTpK&O{&b6p0gLeVZOB3p?6TQV>2EpB(iQkYb)W3PUkUKZxpjV)vJQ zr`VN^sodoP^p*i`Op(i-gjsMd@{^ByXvPLfK6@7;fb?T!qA^Gso%(Cce<%D#GwF1=ob4`y^xLoVFD$ttpKi@IS@jr57YwJ9GhM z+U6zqzJFkM<4%)k!#hVN;mLHPct-L)&`fjTDxhzG{UHg8Nff7g@;agklFi*%HQ zjrZ&97{EFb78>L2^hTuN@-tR0IXkG4CK-%}Xq(JetJSr|v|u|MrXc~aDO&gWcue`Vq9#XH9xu&4o z@TdB@HE7W1*3q}Jud!$IYkZacc9QfN!YUvNCO|fb}AL z$%-L@%bg=5j*rz6&~@)Z2^AETTtBq~=khyfaE-3w$hYN&Su)xk!=)}>atCvlcpMV? z?_Omi-1rTX=-kmAF6O%lWVY#thZUGNH~`yS@nSwr6ZH`Ws#c~5CbpQs&f6mwPONBJ zgtbnP&`#lJ#0y`=%;oIcl(w2vebNWSxYc1?s7GQ1LO^HW1S)Q12Cw4DVV^0gwl8q+ zhx3s}5vh){xa@=1MseqOSxm=J&JMY*H3H&rt`k}F*gtdtr|l|@G8q&KO;7#jrZr6A zOJ!E8jc079YK$cxY!UH&333EQz)TCjDEw#`pL0eY?s0glFk@UhGW3c?T2y*6nKGHv z`D87UNX{_+i6Wl-Yy_6ftbdZl7N~8&^gyawdeP5`MI4AWT-ww`9^@03n_ZWR;VGr? z(uEJR5Q3OWm@JxMp8CR0}cV})$##TIT`ciw&$CLXhJ|56Scz6h61N%m8J z@`Tc1{}FqhoOrWuMM(gMdEwM7IBFXgtbL!8e5visvwf?Ce|^3395}AFb1$7!>n?3n zG+&xEW!`;6faF2?@eRQA?2+SPeR?12pwSAU|E7*dQi2ILZi)62>4zqjDMjj&yfz&~ z7P9wPWDCv2PS2revyF*o{T-(GAPOcVSwqoT{FVfl8IM8v_1}EA0voTnXi0N#PIFCb zY~1~}+Tk6p&YhG>Ox$`p>d{wl^m7+xy`=7wbTD0O4o6qtww*T#D+%KiDe7g1uG2`t&!Wnjdbev zOEq8Z1F^~ExGA+itj*5VlLna%;=>Rep84~`st-RHU^SGS8K>^5AKI|k>^jsmzYNpe zR}xzS#Vg%mD2MtbOihS>NCU&f&zvquAhsZg>+RQNQ{UMCSJ}DySXD(~`~bqt;0rqv zDJYDUo@j!RM&bwrCP5&8N;d&SCK1DAGCWFRG%+@W*jX6=0PQJhY%Gk8i8jW9l9(we zDExijT5F$uhk?YKoZRzRXP^C8@4fcg&3nNYG8R1DI^u}4Iz|i8kbrILR3{OWmK|Jn zne7xx?d!||kd`-}(pjQVo?1mA=F7GeLnI$RH~}WMl@bkIwauF8sij)$r-@BSV&^AL z9bP;!Z6Dex?QLR>)?2|Yl^}vNs7_F$C!s@AY__U9CmrG5Y!+xKp0!4qAtkA1%$Y1Z z=n67W(quM3iItHp#LO+U0+OT`c9)O>{+H{Z?cT8%ZdIVxlf@utSt2ehSWm3`q4$^p z5Pbqa&ElE2#LB|PX8TDOCFw#H$#AunTZ&eO!Oiz#``Sd=3QBN!tSEb^#do`e z1SJC|W?3!=(?Lo`KGdejbO&OP-bJ%UAth8;wb6GNfWq+ZfgJ6o%z z9IRc|zS3l@XGYlC5aDrzK@}IVOb_|c*1s7cW)li!w21n7^|~lK)9l_1d!#z3$GZrh zE=p*+eWZG(0&-~u4?^#YyzJa%8Y8z_!HEX=b7Fsx}KL)w0mg@odJ`-sI9e)cDZ$7Q+;_}2`)o` zbly*+sT)?NDV;!|Yi2K;wi3}mjxlxyez1ViFRfM z!t-ZFB29mAW7g$W{m^_;mI>BDRGGDFX3mzDGc-Blf}GeE>ks)vB9T6pe(n&z!Gjdp zzs6#or`Dw(lc&4LSh*slm|8U*z^YJ3d)YtM5m9C+*NJ7quM>>Kyb<|CWn%L|P8xd+ z<@4OBk4`IvWb0Xn>BdOtHIFBaa;AVVViE@}S!3wj+#i8Pb$$kv%LDA;2wmpkWl zsWXVVy*Fijwd#lkDHF2eShgPA6hH(NWh95qj<&PwrlJBGDzKqD<>-{{rIZ-5k|Oal z6{`VO9L|0VCvV)io{k7GwGL{=ZzoQ&Ml8~rN|=>DF?NW8{5tjU zXqK{F?pWbq^1>(8R_O;*FwV3GvBW>xwAv|!U^Z_>avd0}7GR=Ay4=GIj1#ZA3F_Ht zf||jY@ub5Fpf~SL0Zvp%YQ+;qJA)<8j&e-Jmu-#y5@aUAjUH8mLoBDUF)+#G@Hqr8 zh1yZqsOu$^aqm1ai|-Qbk^qiOXl%!`Ah{gT)EDyI!O+xF-jpB@aTMMPle}S#(zF8t z&(U^RjY8|oWsU`XB8HWJlqBN3vSp@xZ)q$tOwn1Qqy1N;tZ{;wONB2-c!Ue}ZR03Z zZLOpWVAQIX3}B=ov5cZMq~~w$bazH;P~lT5RgsG0?X9M#(*+@qtOB(nql@d6QT@el zY&RrB&A=~-55?Z$+y*~sn%^tKs1kk@#ggvc?ss` zxF40Qf)Vlrj^2!z$qKHaKG10D7E!awQHn5e&q=}y1oo-S| zR@d~Y>pAVJl!q}eUOTDokuto(?iO~Ia6`MsxvvXv#S^)&RsRtKH#;u8$VMIRca=q( z9dd1!&j zlgE}nK6>V?wkJP(?#$B3V{S}HTI&ZvXCAa}a?X(i8ZCzr^m4tkHj@;@f72$AaaZH- zr@?Sa&(lcL^fk?%^kp_VldMEskX`o72WCZ=dda&UObp7D=B?0#Ol;J_*3e4+CXQP@ z{)Fnw*R4!xBELc!)Q&E%zsFEoXw6}l9Ugcr$B;(&!i^bxd4>X*JyiF+xmwqg8qzSo&`P9znXs)C5%+u-4j^^4`oDJq16?GLE@1Z?!Gg}nt z*q`1xP&Clt9fjC2OIOHFn~l|t>V}vGuw3O* zld$lt^BJW>HyJL^ntQb*rfQ*e7+!=*9V=d)&*Xw|23ISVD;5y!H%V@eO`xhYq9sw7 zjB&FTBO#ctUNGV0P=IA#cEo*?VpfF6hgAs06Hl&G#UM4lA<`5@Dh_08QBc#SZHq}` znD(g(9z}0Vo)ipfO{x@vZ_dpQtbFu5F4u%2@tv|W{Vl^Vvg%D~7Dnkh{$Hsx)@NNF zaUhL~arl(1=);IDJ~HDvjIPY6Y^K9#ni=J+1mK!IBje(k4@c~L6&R<=vp!y4;p>Xb z99{O}2TO0RU$~N2Y@PPGmNAa&QN%hy3Gt!iYyL!?3&z!9h5pEw#xV@9b?-ly=Oh0M9D+L!+^4jv7= zI97mL;o=3(>sRHy$Blwp2X38<{RPB-!5!}4?gMupxO;bYHput$Y^j60b$8cr>+Vk1 zrvR(GQwgVb+y?G8aH~J7Ch=1n^!tQEcLld`Xr6;!+QCKss=SL_1GoAm{~L?IEzS+| zfL09)?u&qPd5@0I508$|wKl5Ag1gCijmKl)9s{>u0QoDpuemO`eM|GhzNNY0Rsr!} zaNlvRcI@EBpMNcI%xyUy-vgtz3+@4M4}jaxb^WTmAGz@ohq|KRs?WIP?+W%Oj+Z$E z_mJ`)QeKt8tp<0GbJvgm4d6CZzt;s3zbg9|E(>lLc5^j99MIt8Pi5=)m80MeZr?o| z+&(}2^I`(=SLOYl=c?b{J-a#Phi~3^67COfsl2!Hk>I-O`I(;o%|ThK2{s%8?wz{e zUoiUVzpM7J4%{AyZZG$Lpq^@j=t{Jvy4CNiBMZax-`3Ss-YeYd;qLslF#J1#weS81 D=2=6M literal 0 HcmV?d00001