pax_global_header00006660000000000000000000000064132742515730014523gustar00rootroot0000000000000052 comment=2df702d33428ef955dbe8ef80075f021789919c1 checkit_tiff-0.4.2/000077500000000000000000000000001327425157300141505ustar00rootroot00000000000000checkit_tiff-0.4.2/.gitignore000066400000000000000000000001021327425157300161310ustar00rootroot00000000000000*.o build/* src/.depend src/checkit_check_config src/checkit_tiff checkit_tiff-0.4.2/BUGS000066400000000000000000000001011327425157300146230ustar00rootroot00000000000000* parser could not handle valuedata yet (use ANY as workaround) checkit_tiff-0.4.2/FAQ000066400000000000000000000073271327425157300145130ustar00rootroot00000000000000Q: "make" reports "usage: git rev-list [OPTION] …" A: the Makefile uses version.mk to build a version information for the tool. In that case you should comment out the lines in version.mk and set REPO_REVISION manually Q: I did not have "peg" and my config_dsl.grammar.c has zero size and there are compile errors. A: remove that file and use "git checkout config_dsl.grammar.c" to restore it from repository. Try to avoid "make distclean", because it erases the file. Q: My C-compiler reports error-messages like "cc: error: unrecognized command line option '-fsanitize=undefined'" A: You use an older GCC variant. Try 'SANITIZE="" make' Q: How can I compile a windows version of your program? A: I have only tested creating Windows executables using the crosscompiler minGW under Debian Jessie. You need the installed mingw-w64-x86-32 packages, also you need to download and extract libpcre. in libpcre (pcre-8.37), call "./configure --host=i686-w64-mingw32 --disable-win32-io --disable-shared -enable-static" and "make -j 4". Change into checkit-tiff/build, call: "cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-mingw32.cmake ../src/ -DPCRE_LIBRARY=~/Downloads/pcre-8.37/.libs/libpcre.a -DPCRE_INCLUDE_DIR=~/Downloads/pcre-8.37/ ../src/" and "make -j 4" A2: I have only tested creating Windows executables using the crosscompiler minGW under Debian Jessie. You need the installed mingw-w64-x86-64 packages, also you need to download and extract libtiff and libpcre. in libpcre (pcre-8.37), call "./configure --host=x86_64-w64-mingw32 --disable-win32-io --disable-shared -enable-static" and "make -j 4". Change into checkit-tiff/build, call: "cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-mingw64.cmake ../src/ -DPCRE_LIBRARY=~/Downloads/pcre-8.37/.libs/libpcre.a -DPCRE_INCLUDE_DIR=~/Downloads/pcre-8.37/ ../src/" and "make -j 4" Q: How to compile to Javascript? A: Use emscripten, do same steps as above but with "emconfigure ./configure...". Compile checkit_tiff with ff. options: $> emcmake cmake -DCMAKE_C_COMPILER=$(which emcc) -DPCRE_LIBRARY=~/Downloads/pcre-8.37/.libs/libpcre.a -DPCRE_INCLUDE_DIR=~/Downloads/pcre-8.37/ -DCMAKE_C_FLAGS="-Oz -s TOTAL_MEMORY=400000000" ../src/" $> make -j 4 $> js checkit_tiff.js -c ../tiffs_should_pass/minimal_valid.tiff ../example_configs/cit_tiff6_baseline_SLUB.cfg Q: Where are older TIFF specs? A: take a look to: TIFF 4: https://web.archive.org/web/20050323073243/http://palimpsest.stanford.edu/bytopic/imaging/std/tiff4.html TIFF 5: https://web.archive.org/web/20050323073243/http://palimpsest.stanford.edu/bytopic/imaging/std/tiff5.html Q: I am using cmake, but it fails with "CMake Error: your CXX compiler: "CMAKE_CXX_COMPILER-NOTFOUND" was not found. Please set CMAKE_CXX_COMPILER to a valid compiler path or name". But your program is C only, why I need a C++compiler then? A: cmake uses C++-compiler for its checks. Sorry, you need a C++ then. Q: Your tool processes very slow, why? A: No, the tool is optimized for very fast processing. On a NVME-based SSD it processes 550 TIFF files (2,9GB) in less 3 seconds. We have tested it also on our NFS based filesystem with similar fast results. There is only one cornercase, if you have a broken TIFF with very large IFDs. Because checkit_tiff tries to find all errors in a given TIFF file it does not use early aborts than some other tools. Q: I have a fully destroyed TIFF because checkit_tiff reports IFD errors. Is there any chance to repair the file? A: You could give "fixit_tiff" a try: https://github.com/SLUB-digitalpreservation/fixit_tiff This project comes with some helper tools to find lost IFDs and could fix some typical errors in broken TIFF files. checkit_tiff-0.4.2/LICENSE000066400000000000000000000033121327425157300151540ustar00rootroot00000000000000The software uses some pieces from libtiff, therefore the whole project is licensed under same conditions, too. (c) 2015-2018 Andreas Romeyke Copyright (C) 1988-1997 Sam Leffler Copyright (C) 1991-1997 Silicon Graphics, Inc. Portions Copyright (C) 1985-1987, 1990 Regents of the University of California Portions Copyright (C) 1990, 1991 Digital Equipment Corporation Portions Copyright (C) 1990 Sun Microsystems, Inc. Portions Copyright (C) 1990, 1995 Frank D. Cringle Portions Copyright (C) 1996 BancTec AB Portions Copyright (C) 1996 Mike Johnson Portions Copyright (C) 1996 Pixar Portions Copyright (C) 1997 Greg Ward Larson Portions Copyright (C) 2000 Frank Warmerdam Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that (i) the above copyright notices and this permission notice appear in all copies of the software and related documentation, and (ii) the names of Sam Leffler and Silicon Graphics may not be used in any advertising or publicity relating to the software without the specific, prior written permission of Sam Leffler and Silicon Graphics. THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. checkit_tiff-0.4.2/README.1st_checkit000066400000000000000000000041661327425157300172370ustar00rootroot00000000000000General ======= "checkit_tiff" is a conformance checker for baseline TIFFs (with various extensions). It works in different way than other tools. Instead to use a hardcoded rule set with predefined values, you are able to define tags and corresponding values more fine granulary. The rulesets are human readable and could be adapted to own needs. The "checkit_tiff" works on commandline and therefore it is embeddable in scripts The tools are developed for purposes of curation and longterm preservation In detail ========= checkit_tiff: - checks a TIFF against ruleset - needs a Linux or an AIX system with installed libtiff4 (crosscompiling to Windows should work, too) - to compile, please read README.compile - help comes with option "checkit_tiff -h" License ======= the sourcecode is licensed under conditions of libtiff, see http://libtiff.maptools.org for details. HINTS ===== * The program could already be used to check TIFF-files now * Remember, it is in alpha-state and needs additional rules to validate tiff files completely. * Please, if you find errors or do you have test files like ** https://github.com/EasyinnovaSL/DPFManager/tree/develop/src/test/resources/ ** or https://github.com/openpreserve/jhove/tree/junit_tests/examples/tiff/badfiles * please do not hesitate to contact me. * to *repair* TIFFs, you could give "fixit_tiff" a try: https://github.com/SLUB-digitalpreservation/fixit_tiff == Compile == see file 'README.compile' for details, in short: == Run == Use the builtin help via './checkit_tiff -h' Here is an example output using $> checkit_tiff -q example_configs/cit_tiff6_baseline_SLUB.cfg tiffs_should_fail/invalid_date.tiff './build/checkit_tiff' version: development revision: 393 licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html) cfg_file=example_configs/cit_tiff6_baseline_SLUB.cfg tiff file/dir=tiffs_should_fail/invalid_date.tiff file: tiffs_should_fail/invalid_date.tiff (EE) tag 306 (DateTime) --> DateTime tag should contain a valid value. DateTime tag has wrong format.; found: 04.03.2010 09:59:17 (lineno: 146) (EE)Found 1 errors (EE)No, the given tif is not valid :( checkit_tiff-0.4.2/README.TIFFrisks000066400000000000000000000066451327425157300166460ustar00rootroot00000000000000Some thoughts about risks in TIFF file format ============================================= == Introduction == TIFF in general is a very simple fileformat. It starts with a constant header entry, which indicates that the file is a TIFF and how it is encoded (byteorder). The header contains an offset entry which points to the first image file directory (IFD). Each IFD has a field which counts the number of associated tags, followed by an array of these tags and an offset entry to the next IFD or to zero, which means there is no further IFD. Each tag in the array is 12 Bytes long. The first 4 bytes indicate the tag itself, the next 2 bytes declare the value-type, followed by 2 bytes counting the values. The last 4 bytes are either an offset or hold the values themselves. == What makes a TIFF robust? == In the TIFF specification, there are some hints which help us to repair broken TIFFs. The first hint is that all offset-addresses must be even. The second important rule is that the tags in an IFD must be sorted in an ascending order. At last, the TIFF spec defines different areas in the tag range. This is to guarantee that the important values are well defined. If we guarantee that a valid TIFF was stored, there is a good chance to detect and repair broken TIFFs using these three hints. == What are the caveats of TIFF? == As a proof of concept there is also a tool "checkit_tiff_risks" provided in this repository. Using this tool, users can analyze the layout of any baseline TIF file. The most risky memory ranges are the offsets. If a bitflip occurs there, the user must search the complete 4GB range. In practise, the TIF files are smaller, and so this size is the searchspace for offsets. The most risky offsets are the ones which are indirect offsets. This means the IFD0 offset and the StripOffset tag (code 273). Here an example of a possible complex StripOffset encoding: [ditaa] ---- +-------------+ | TIFF header |--\ +-------------+ | | /-----------/ Offset to IFD0 | v +-------------+ | IFD0 | |-------------| | ... | | StripOffset |--\ +-------------+ | | Offset to values /-----------/ of tag StripOffset | v +-------------+ | StripOffs. 0|----\ | StripOffs. 1|--\ | Offset to pixel-data +-------------+ | | of stripe 0 | | /-----------/ | | | v | +-------------+ | | pixel-data 1| | +-------------+ | | /-------------/ | v +-------------+ | pixel-data 1| +-------------+ ---- The problem in this example is that TIFF has no way to find out how many bytes are part of the pixel-data stream. The existing StripByteCounts tag only stores the expected pixel data length *after* decompression. This makes the StripOffset tag very fragile. If a bitflip changes the offset of the StripOffset tag, the whole pixel information might be lost. Also, if a bitflip occurs in the offset area that the StripOffset tag points to, the partial pixel data of the affected stripe is lost. If compression is used, the risk of losing the whole picture is even higher, because the compression methods do not use an end-symbol. Instead, the buffer sizes as stored in the StripByteCount tag are used. Therefore, a bit-error in the Compression tag, the StripOffset tag, the StripByteCount tag or in the memory-map where StripOffset points to, could destroy the picture information. checkit_tiff-0.4.2/README.TIFFspecification000066400000000000000000000013771327425157300203300ustar00rootroot00000000000000== EXIF IFD (and other private IFDs) == Because Adobe registers the private TIFF-tags, we know little about these tags in the wild. In the specification it would be suggested to use a special IFD if you need more than small amount of private TIFF tags. This affects also the tags used for EXIF data. Our interpretation is, if you have an IFD for private tags, they should only be referenced from this IFD and not from base IFD directly. == offsets on word boundary == The specification is very clear. Offsets should only point to odd addresses. We think this is important for longterm preservation, because it makes the TIFF format more robust and repairable if some bit flipping occurs. == tags in ascending order == see offset and word boundary, same reason checkit_tiff-0.4.2/README.compile000066400000000000000000000051331327425157300164610ustar00rootroot00000000000000# You need an installed cmake ######################################################## # compiling under linux ######################################################## mkdir build cd build cmake ../src/ -DCMAKE_C_FLAGS="-W -Wall -Wextra -ansi -pedantic -O2 -Wno-unused-function" make ### # if you want to allow preferred CMM type "LINO", you should use the cmake-call # cmake ../src/ -DCMAKE_C_FLAGS="-DALLOW_CMMTYPE_LINO -W -Wall -Wextra -ansi -pedantic -O2 -Wno-unused-function" ######################################################## # alternatively for windows crosscompiling using mingw ######################################################## #mkdir build #cd build #cmake -DCMAKE_TOOLCHAIN_FILE=../src/toolchain-mingw32.cmake -DPCRE_LIBRARY=~/Downloads/pcre-8.37/.libs/libpcre.a -DPCRE_INCLUDE_DIR=~/Downloads/pcre-8.37/ ../src/ #make # ######################################################## # examples/options to set specific C-compiler or Flags ######################################################## # cmake ../src/ -DCMAKE_C_COMPILER=$(which gcc) # cmake ../src/ -DCMAKE_C_FLAGS="-O0 -p -g" # cmake ../src/ -DCMAKE_C_COMPILER=$(which clang-3.5) -DCMAKE_C_FLAGS="-Oz -pedantic" # ######################################################## # example SANITIZE options ######################################################## # # SANITIZE with clang++ # cmake ../src/ -DCMAKE_C_COMPILER=/usr/bin/clang-3.5 -DCMAKE_C_FLAGS="-O0 -g -fsanitize=address -fno-omit-frame-pointer" # make # ASAN_OPTIONS=detect_leaks=1 ./checkit_tiff ... # # SANITIZE with gcc # cmake ../src/ -DCMAKE_C_FLAGS="-Og -g -fsanitize=address -fno-omit-frame-pointer" # AFL_HARDEN=1 make # ASAN_OPTIONS=detect_leaks=1 ./checkit_tiff ... # # ######################################################## # example STATIC options ######################################################## # # cmake ../src/ -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc" -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" -DPCRE_LIBRARY=/usr/lib/x86_64-linux-gnu/libpcre.a # ######################################################## # example CLANG-TIDY ######################################################## # cmake ../src/ -DCMAKE_C_CLANG_TIDY:STRING="clang-tidy;-checks=-*,readability-*" -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DCMAKE_C_COMPILER=/usr/bin/clang-3.8 -DCMAKE_C_FLAGS="-O0 -g -fsanitize=address -fno-omit-frame-pointer" # make # run-clang-tidy-3.8.py -clang-tidy-binary /usr/bin/clang-tidy-3.8 # # ######################################################## # Testing ######################################################## # you need perl with Test::More # change to directory "t/" # run "perl -I ./ *.t" # checkit_tiff-0.4.2/README.grammar000066400000000000000000000100621327425157300164540ustar00rootroot00000000000000About general function ====================== The checkit-tool validates TIFF-files against a set of rules (see below). The set of rules works as a whitelist. This means that TIFF tags that are used in the file but not explicitly checked by a specific rule (not considering if successful or not) are not allowed. In cases where a rule is executed only if a predicate is set, the tag is only allowed if the predicate check succeeded. Developers ========== to configure the grammar you could use the PEG-extension for gvim from https://github.com/gf3/peg.vim To visualize the grammar, checkout this tools: * http://bottlecaps.de/convert/ * http://bottlecaps.de/rr/ui The actual grammar is visualized in grammar.xhtml Users ===== To define your own config-file for checking TIFFs, please use this simplified syntax: * Each line is either a "modeline", an "include" line, a "tag" line, a comment or empty * TODO: a modeline uses "mode(MODE)", MODE could be: ** "baseline", if no modeline is defined, it defaults to "mode(baseline)", too ** "extended" * To include a configfile, use "include(FILENAME)", where FILENAME is a correct path * Comments starts with '# '. They are only allowed to start right at the beginning of a new line. * A tagline is built as "TAG; REQUIREMENTS; VALUES", where * a TAG is an increasing number similar to TIFF-Tag numbers (see TIFF specification) * REQUIREMENTS could be ** 'mandatory' - a tag must exist in TIFF ** 'optional' - a tag may exist in TIFF, if it does, it will be checked ** 'depends(REFERENCE)' - a tag must exist in TIFF if reference exists ** 'optdepends(REFERENCE)' - a tag may exists in TIFF if reference exists. If it exists it will be checked * The syntax for a REFERENCE is TAGREFERENCE.VALUEREFERENCE ** TAGREFERENCE points to a tag number which must be exist, ** VALUEREFERENCE can be one of: *** 'any' (which means any match) or *** a decimal value or *** 'range(START, END)', where START and END are decimal values *** 'only(VALUE)', where VALUE is a decimal value *** 'ntupel(VALUE, ..), decimal values as n-tupel enclosed in brackets *** 'regex("REGEX")', where REGEX is a Perl compatible regular expression (PCRE) with escaped '"' and '\', it only works with tags of type ascii ** only if REFERENCE exists in TIFF the REQUIREMENTS rule will be checked ** The REQUIREMENTS rule will only be checked if REFERENCE exists in the TIF file. * VALUES can be one of: ** 'range(START, END)', where START and END are decimal values ** 'logical_or( VALUELIST)', where VALUELIST are comma-separated decimale values or ntupels ** 'any', which means any match ** 'only(VALUE)', where VALUE is a decimal value ** 'ntupel(VALUE, ..), decimal values as n-tupel enclosed in brackets ** 'regex("REGEX")', where REGEX is a Perl compatible regular expression (PCRE) with escaped '"' and '\', it only works with tags of type ascii * each tagline or comment must be closed with a new line If multiple rules are defined per tag, they will be combined. For examples, please check the 'example_configs/' - directory. Values ====== At the moment, the parser only supports a limited type of values. To make handling easier, it uses only the value/offset part of an IFD entry. Test if grammar parser works correctly ====================================== You could use the program '/checkit_check_config < your.cfg', this would print a reversed stack ouput, how echa rule will be applied. For example, if your rule is ---- 258; optdepends(262.1); logical_or(1, 4, 8)' ---- it will print: ---- ((( parse config file ))) ((( execute execution plan ))) ((( clean execution plan ))) ((( print internal execution plan ))) /* the rules are in stack order, the top comes first */ /* lineno=001 */ PRECOND: fc_tag_quiet tag=258 top i stack=(0) /* lineno=001 */ PRECOND: fc_tag_has_value_quiet tag=262 top i stack=(1) /* lineno=001 */ EXEC: fc_internal_logic_combine_open tag=258 top i stack=(1) /* lineno=001 */ EXEC: fc_tag_has_value tag=258 top i stack=(1) /* lineno=001 */ EXEC: fc_tag_has_value tag=258 top i stack=(4) /* lineno=001 */ EXEC: fc_tag_has_value tag=258 top i stack=(8) ---- checkit_tiff-0.4.2/README.icc000066400000000000000000000003061327425157300155640ustar00rootroot00000000000000the ICC validation code is very alpha. Please also check the ICC Signature Registry at http://www.color.org/signatures2.xalter and inform me if you find a bug in checkit_tiff using git-repository checkit_tiff-0.4.2/README.regex000066400000000000000000000010251327425157300161370ustar00rootroot00000000000000= RegEx = the program uses the pcre-library for regular expressions in ascii matching rules (in config file). If you use a regex similar to "^[:print:]*$" it does not match on * all strings containing characters outside of printable ascii range (see 'man pcre2pattern' for details) * an empty string "" will not matched, because we defined PCRE_NOTEMPTY. An empty string is not a valid match, this behaviour is a design choice. * Unicode is not set, because TIFF specification is in general ASCII based (PCRE_UTF8 not set) checkit_tiff-0.4.2/TODO000066400000000000000000000004261327425157300146420ustar00rootroot00000000000000- add checks for XMP specification http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMP%20SDK%20Release%20cc-2014-12/XMPSpecificationPart1.pdf - add checks for IPTC specification http://www.iptc.org/download/download.php?fn=IIMV4.1.pdf - add more testfiles checkit_tiff-0.4.2/common/000077500000000000000000000000001327425157300154405ustar00rootroot00000000000000checkit_tiff-0.4.2/common/doxygen.conf000066400000000000000000002374531327425157300200020ustar00rootroot00000000000000# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = checkit_tiff # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "validates baseline TIFFs" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, # Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, # Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields or simple typedef fields will be shown # inline in the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO (the default), structs, classes, and unions are shown on a separate # page (for HTML and Man pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can # be an expensive process and often the same symbol appear multiple times in # the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too # small doxygen will become slower. If the cache is too large, memory is wasted. # The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid # range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 # symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = YES # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c \ *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be ignored. # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search # engine library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4 will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images # or other source files which should be copied to the LaTeX output directory. # Note that the files will be copied as-is; there are no commands or markers # available. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files # that can be used to generate PDF. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. If left blank docbook will be used as the default path. DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed # in the related pages index. If set to NO, only the current project's # pages will be listed. EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # manageable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES checkit_tiff-0.4.2/common/peg2pegjs.pl000066400000000000000000000002271327425157300176640ustar00rootroot00000000000000#!/bin/bash # converts a PEG grammar in a PEG.js grammar fgrep -v "set_parse_error" | sed -e "s/^#.*//g" -e "s/<-/=/g" -e "s/[<>]//g" -e "s/[\t ]#//g" checkit_tiff-0.4.2/example_configs/000077500000000000000000000000001327425157300173135ustar00rootroot00000000000000checkit_tiff-0.4.2/example_configs/README.txt000066400000000000000000000013521327425157300210120ustar00rootroot00000000000000cit_tiff_baseline_minimal.cfg Defines rules for checking files against the Baseline TIFF 6 specification. cit_tiff6_baseline_SLUB.cfg Like "cit_tiff_baseline_minimal.cfg", but with the extensions as defined in http://www.slub-dresden.de/ueber-uns/slubarchiv/technische-standards-fuer-die-ablieferung-von-digitalen-dokumenten/handreichung-tiff/ cit_tiff-a_whitepaper.cfg Defines rules for checking files against the TI-A's preliminary specification as in http://www.ti-a.org/TI-A%20Whitepaper.pdf cit_tiff6_complete.cfg ruleset to allow all TIFF6 variants (only IFD0) cit_tiff6_geotiff_SLUB.cfg similar to "cit_tiff6_baseline_SLUB.cfg" but for GeoTIFFs cit_tiff_ep.cfg ruleset to allow TIFF/EP files (only IFD0) checkit_tiff-0.4.2/example_configs/cit_tiff-a_whitepaper.cfg000066400000000000000000000212001327425157300242240ustar00rootroot00000000000000# This defines a sample config for baseline tiffs, based on Whitepaper of the # TI-A initiative (2016-05), see http://www.ti-a.org/TI-A%20Whitepaper.pdf # tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) | optdepends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # Remember, because it works as whitelist for each required tag we need an # entry here ##### # Required Baseline Tags ##### # 256 0100 ImageWidth The number of columns in the image, i.e., the number of pixels per row. 256; mandatory; range(1, 4294967295) # 257 0101 ImageLength The number of rows of pixels in the image. 257; mandatory; range(1, 4294967295) # 258 0102 BitsPerSample Number of bits per component. ##########################258; mandatory; logical_or(8,16) # Bitonal is optional, grey & RGB is mandatory. If 262 AND 258 exist, then the values need to be in the specified range. 258; depends(262.2); ntupel(8,8,8) #258; depends(262.2); only(16,16,16) # needs to be fixed in parser 258; depends(258.any); logical_or(4, 8) # 259 0103 Compression Compression scheme used on the image data ### (1 means no compression) 259; mandatory; only(1) # 262 0106 PhotometricInterpretation The color space of the image data. ### 2 means RGB, 0 and 1 means bilevel or grayscale, 0 is unusual, 3 is Palette Color (FORBIDDEN), 4 is Transparency Mask (FORBIDDEN) 262; mandatory; range(1, 2) # 273 0111 StripOffsets For each strip, the byte offset of that strip. 273; mandatory; any # 277 0115 SamplesPerPixel The number of components per pixel. ### if RGB then 3 else 1 ### Even though Baseline TIFF allows for SamplesPerPixel>3, we do NOT allow this for long term archival. 277; depends(262.2); only(3) 277; depends(262.1); only(1) # 278 0116 RowsPerStrip The number of rows per strip. 278; mandatory; range(1, 4294967295) # 279 0117 StripByteCounts For each strip, the number of bytes in the strip after compression. 279; mandatory; range(1, 4294967295) # 282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction. 282; depends(296.any); range(300, 1200) # 283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction. 283; depends(296.any); range(300, 1200) # 296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution. 1 = No absolute unit of measurement. 2 = Inch. 3 = Centimeter. Default: 2 296; optional; any ##### # optional fields ##### # NO OTHER VALUES FROM THE RANGE (0 - 7) ARE ALLOWED. ONLY "0" IS SUITABLE FOR LONG TERM ARCHIVAL. # 254 00FE NewSubfileType A general indication of the kind of data contained in this subfile. These values are defined as bit flags because they are independent of each other. Default is 0. #254; optional; only(0) # DO NOT UNCOMMENT! THIS TAG IS DEPRECATED! USE NEW SUBFILE TYPE INSTEAD! # 255 00FF SubfileType A general indication of the kind of data contained in this subfile. This field is deprecated. The NewSubfileType field should be used instead. #255; optional; range(1, 3) # DO NOT UNCOMMENT! THRESHOLDING IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 263 0107 Threshholding For black and white TIFF files that represent shades of gray, the technique used to convert from gray to black and white pixels. Default is 1. #263; optional; range(1, 3) # DO NOT UNCOMMENT! CELL WIDTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 264 0108 CellWidth The width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. #264; depends(263.2); any # DO NOT UNCOMMENT! CELL LENGTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 265 0109 CellLength The length of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. This field should only be present if Threshholding = 2. #265; depends(263.2); any ### Support for FillOrder=2 is not required in a Baseline TIFF compliant reader. Default is 1. # 266 010A FillOrder The logical order of bits within a byte. #266; optional; only(1) # 270 010E ImageDescription A string that describes the subject of the image. #270; optional; regex("^[[:print:]]*$") # 271 010F Make The scanner manufacturer. #271; optional; regex("^[[:print:]]*$") # 272 0110 Model The scanner model name or number. #272; optional; regex("^[[:print:]]*$") # 274 0112 Orientation The orientation of the image with respect to the rows and columns. Default is 1, and only this value is Baseline TIFF conform. # 274; optional; range(1, 8) # THIS IS NOT BASELINE TIFF!!! DO NOT UNCOMMENT!!! #274; optional; only(1) # 280 0118 MinSampleValue The minimum component value used. Default is 0. #280; optional; any # 281 0119 MaxSampleValue The maximum component value used; only for statistical purposes. Default is 2**(BitsPerSample) - 1. #281; optional; any # 284 011C PlanarConfiguration How the components of each pixel are stored. 1 = Chunky format. 2 = Planar format and Baseline TIFF readers are not required to support it. Default: 1. #284; optional; only(1) # DO NOT UNCOMMENT! FREE OFFSETS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 288 0120 FreeOffsets For each string of contiguous unused bytes in a TIFF file, the byte offset of the string. Not recommended for general interchange. #288; optional; any # DO NOT UNCOMMENT! FREE BYTE COUNTS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 289 0121 FreeByteCounts For each string of contiguous unused bytes in a TIFF file, the number of bytes in the string. Not recommended for general interchange. #289; optional; any # 290 0122 GrayResponseUnit The precision of the information contained in the GrayResponseCurve. Default: 2; Recommended: 3 #290; optdepends(262.0); range(1, 5) #290; optdepends(262.1); range(1, 5) # 291 0123 GrayResponseCurve For grayscale data, the optical density of each possible pixel value. 291; optdepends(262.0); any 291; optdepends(262.1); any # 297 PageNumber actual page, and total pagecount, the actual page count starts with 0; Recommended: 0, 1 #297; optional; only(0,1) # 305 0131 Software Name and version number of the software package(s) used to create the image. #305; optional; regex("^[[:print:]]*$") # 306 0132 DateTime Date and time of image creation in the format "YYYY:MM:DD HH:MM:SS". 306; optional; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") # DO NOT UNCOMMENT! ARTIST IS NOT SUITABLE FOR LONG TERM ARCHIVAL DUE TO PRIVACY CONCERNS! # 315 013B Artist Person who created the image. Some older TIFF files used this tag for storing Copyright information. #315; optional; any # DO NOT UNCOMMENT! HOST COMPUTER INFORMATION IS NOT SUITABLE AND IRRELEVANT FOR LONG TERM ARCHIVAL! # 316 013C HostComputer The computer and/or operating system in use at the time of image creation. #316; optional; any # DO NOT UNCOMMENT! COLOR MAP TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 320 0140 ColorMap This field defines a Red-Green-Blue color map (often called a lookup table) for palette color images. #320; optional; any # DO NOT UNCOMMENT! EXTRA SAMPLES TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL BECAUSE THEIR MEANING CANNOT BE DOCUMENTED! # 338 0152 ExtraSamples Description of extra components. #338; optional; range(0-2) # 700 02BC XMP XML packet containing XMP metadata. #700; optional; any # 33432 8298 Copyright Complete copyright notice of the person or organization that claims the copyright to the image. 33432; optional; regex("^[[:print:]]*$") # IPTC METADATA ARE NOT SUITABLE FOR LONG TERM ARCHIVAL, but could be ignored # 33723 83BB IPTC IPTC (International Press Telecommunications Council) metadata. 33723; optional; any # PHOTOSHOP METADATA ARE PROPRIETARY AND HENCE NOT SUITABLE FOR LONG TERM ARCHIVAL, but could be ignored # 34377 8649 Photoshop Collection of Photoshop 'Image Resource Blocks'. 34377; optional; any # 34665 8769 Exif IFD A pointer to the Exif IFD. Exif IFD is a set of tags for recording Exif-specific attribute information. It is pointed to by the offset from the TIFF header (Value Offset) indicated by an Exif private tag value. An Exif IFD has the same structure as that of the IFD specified in TIFF. Ordinarily, however, it does not contain image data as in the case of TIFF. 34665; optional; any # 34675 8773 ICC Profile ICC Profile data 34675; optional; any ##### # unanswered questions ##### # - Image File Directory (IFD) # => genau 1 IFD muss vorhanden sein # (einerseits min. 1. gefordert, andererseits muss ein Baseline-Tiff-Reader max. 1 lesen) # => Einträge müssen aufsteigend geordnet sein # - Bytes 0-1: Anzahl der IFD-Einträge # => muss mit der tatsächlichen Anzahl übereinstimmen # - 4 Bytes: Offset zum nächsten IFD (oder "0000" falls kein IFD mehr kommt) # => Eintrag muss "0000" sein checkit_tiff-0.4.2/example_configs/cit_tiff6_baseline_SLUB.cfg000066400000000000000000000241311327425157300243410ustar00rootroot00000000000000# tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) | optdepends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # This defines a sample config for baseline tiffs # Remember, because it works as whitelist for each required tag we need an # entry here mode(baseline) mode(enable_type_checks) mode(enable_offset_checks) mode(enable_ifd_checks) ##### # Required Baseline Tags ##### # 256 0100 ImageWidth The number of columns in the image, i.e., the number of pixels per row. 256; mandatory; range(1, 4294967295) # 257 0101 ImageLength The number of rows of pixels in the image. 257; mandatory; range(1, 4294967295) # 258 0102 BitsPerSample Number of bits per component. ##########################258; mandatory; logical_or(8,16) # Bitonal is optional, grey & RGB is mandatory. If 262 AND 258 exist, then the values need to be in the specified range. 258; optdepends(262.0); logical_or(1, 4, 8) 258; optdepends(262.1); logical_or(1, 4, 8) 258; depends(262.2); logical_or(ntupel(8,8,8), ntupel(16,16,16)) # 259 0103 Compression Compression scheme used on the image data ### (1 means no compression) 259; mandatory; only(1) # 262 0106 PhotometricInterpretation The color space of the image data. ### 2 means RGB, 0 and 1 means bilevel or grayscale, 0 is unusual, 3 is Palette Color (FORBIDDEN), 4 is Transparency Mask (FORBIDDEN) 262; mandatory; range(0, 2) # 273 0111 StripOffsets For each strip, the byte offset of that strip. # TODO: 273; mandatory; range(1, 4294967295) # Hint: Because value could be an array, only "any" is used, an array of n elements not supported yet 273; mandatory; any # 277 0115 SamplesPerPixel The number of components per pixel. ### if RGB then 3 else 1 ### Even though Baseline TIFF allows for SamplesPerPixel>3, we do NOT allow this for long term archival. 277; depends(262.2); only(3) 277; optdepends(262.1); only(1) 277; optdepends(262.0); only(1) # 278 0116 RowsPerStrip The number of rows per strip. 278; mandatory; range(1, 4294967295) # 279 0117 StripByteCounts For each strip, the number of bytes in the strip after compression. # TODO: 279; mandatory; range(1, 4294967295) # Hint: Because value could be an array, only "any" is used, an array of n elements not supported yet 279; mandatory; any # 282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction. 282; mandatory; range(300, 4000) # 283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction. 283; mandatory; range(300, 4000) # 296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution. 1 = No absolute unit of measurement. 2 = Inch. 3 = Centimeter. Default: 2 296; mandatory; only(2) ##### # optional fields ##### # NO OTHER VALUES FROM THE RANGE (0 - 7) ARE ALLOWED. ONLY "0" IS SUITABLE FOR LONG TERM ARCHIVAL. # 254 00FE NewSubfileType A general indication of the kind of data contained in this subfile. These values are defined as bit flags because they are independent of each other. Default is 0. 254; optional; logical_or(0, 2) # DO NOT UNCOMMENT! THIS TAG IS DEPRECATED! USE NEW SUBFILE TYPE INSTEAD! # 255 00FF SubfileType A general indication of the kind of data contained in this subfile. This field is deprecated. The NewSubfileType field should be used instead. #255; optional; range(1, 3) # DO NOT UNCOMMENT! THRESHOLDING IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 263 0107 Threshholding For black and white TIFF files that represent shades of gray, the technique used to convert from gray to black and white pixels. Default is 1. #263; optional; range(1, 3) # DO NOT UNCOMMENT! CELL WIDTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 264 0108 CellWidth The width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. #264; depends(263.2); any # DO NOT UNCOMMENT! CELL LENGTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 265 0109 CellLength The length of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. This field should only be present if Threshholding = 2. #265; depends(263.2); any ### Support for FillOrder=2 is not required in a Baseline TIFF compliant reader. Default is 1. # 266 010A FillOrder The logical order of bits within a byte. 266; optional; only(1) # 269 010D Documentname 269; optional; printascii # 270 010E ImageDescription A string that describes the subject of the image. 270; optional; printascii # 271 010F Make The scanner manufacturer. 271; optional; printascii # 272 0110 Model The scanner model name or number. 272; optional; printascii # 274 0112 Orientation The orientation of the image with respect to the rows and columns. Default is 1, and only this value is Baseline TIFF conform. # 274; optional; range(1, 8) # THIS IS NOT BASELINE TIFF!!! DO NOT UNCOMMENT!!! 274; optional; only(1) # 280 0118 MinSampleValue The minimum component value used. Default is 0. 280; optional; any # 281 0119 MaxSampleValue The maximum component value used; only for statistical purposes. Default is 2**(BitsPerSample) - 1. 281; optional; any # 284 011C PlanarConfiguration How the components of each pixel are stored. 1 = Chunky format. 2 = Planar format and Baseline TIFF readers are not required to support it. Default: 1. 284; optional; only(1) # DO NOT UNCOMMENT! FREE OFFSETS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 288 0120 FreeOffsets For each string of contiguous unused bytes in a TIFF file, the byte offset of the string. Not recommended for general interchange. #288; optional; any # DO NOT UNCOMMENT! FREE BYTE COUNTS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 289 0121 FreeByteCounts For each string of contiguous unused bytes in a TIFF file, the number of bytes in the string. Not recommended for general interchange. #289; optional; any # 290 0122 GrayResponseUnit The precision of the information contained in the GrayResponseCurve. Default: 2; Recommended: 3 290; optdepends(262.0); range(1, 5) 290; optdepends(262.1); range(1, 5) # 291 0123 GrayResponseCurve For grayscale data, the optical density of each possible pixel value. 291; optdepends(262.0); any 291; optdepends(262.1); any # 297 PageNumber actual page, and total pagecount, the actual page count starts with 0; Recommended: 0, 1 297; optional; ntupel(0,1) # 305 0131 Software Name and version number of the software package(s) used to create the image. 305; optional; printascii # 306 0132 DateTime Date and time of image creation in the format "YYYY:MM:DD HH:MM:SS". #306; optional; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") 306; optional; datetime # DO NOT UNCOMMENT! ARTIST IS NOT SUITABLE FOR LONG TERM ARCHIVAL DUE TO PRIVACY CONCERNS! # 315 013B Artist Person who created the image. Some older TIFF files used this tag for storing Copyright information. #315; optional; any # DO NOT UNCOMMENT! HOST COMPUTER INFORMATION IS NOT SUITABLE AND IRRELEVANT FOR LONG TERM ARCHIVAL! # 316 013C HostComputer The computer and/or operating system in use at the time of image creation. #316; optional; any # WhitePoint, if RGB, points to chromaticity of the white point of the image.This is the chromaticity # when each of the primaries has its ReferenceWhite value. The value is described using the 1931 CIE # xy chromaticity diagram and only the chromaticity is specified. This value can correspond to the # chromaticity of the alignment white of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. The ordering is white[x], white[y]. # (Source: www.awaresystems.be) # example: CIE Standard Illuminant D65 used by CCIR Recommendation 709 and Kodak PhotoYCC is: # 3127/10000,3290/10000 318; optional; any # PrimaryChromaticities, This is the chromaticity for each of the primaries when it has its ReferenceWhite # value and the other primaries have their ReferenceBlack values. These values are described using the # 1931 CIE xy chromaticity diagram and only the chromaticities are specified. These values can correspond # to the chromaticities of the phosphors of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. # (Source: www.awaresystems.be) # The ordering is red[x], red[y], green[x], green[y], blue[x], and blue[y]. # For example the CCIR Recommendation 709 primaries are: # 640/1000,330/1000, # 300/1000, 600/1000, # 150/1000, 60/1000 319; optional; any # DO NOT UNCOMMENT! COLOR MAP TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 320 0140 ColorMap This field defines a Red-Green-Blue color map (often called a lookup table) for palette color images. #320; optional; any # DO NOT UNCOMMENT! EXTRA SAMPLES TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL BECAUSE THEIR MEANING CANNOT BE DOCUMENTED! # 338 0152 ExtraSamples Description of extra components. #338; optional; range(0-2) # Sampleformat 339; optional; only(1) # 700 02BC XMP XML packet containing XMP metadata. 700; optional; any # 33432 8298 Copyright Complete copyright notice of the person or organization that claims the copyright to the image. 33432; optional; printascii # DO NOT UNCOMMENT! IPTC METADATA ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 33723 83BB IPTC IPTC (International Press Telecommunications Council) metadata. # http://www.iptc.org/download/download.php?fn=IIMV4.1.pdf #33723; optional; any # DO NOT UNCOMMENT! PHOTOSHOP METADATA ARE PROPRIETARY AND HENCE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 34377 8649 Photoshop Collection of Photoshop 'Image Resource Blocks'. #34377; optional; any # 34665 8769 Exif IFD A pointer to the Exif IFD. Exif IFD is a set of tags for recording Exif-specific attribute information. It is pointed to by the offset from the TIFF header (Value Offset) indicated by an Exif private tag value. An Exif IFD has the same structure as that of the IFD specified in TIFF. Ordinarily, however, it does not contain image data as in the case of TIFF. 34665; optional; any # 34675 8773 ICC Profile ICC Profile data. Mandatory for RGB 8-Bit/16-Bit, Optional for Grayscale 34675; optdepends(262.0); iccprofile 34675; optdepends(262.1); iccprofile 34675; depends(262.2); iccprofile checkit_tiff-0.4.2/example_configs/cit_tiff6_complete.cfg000066400000000000000000000363471327425157300235560ustar00rootroot00000000000000# tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) | optdepends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # This defines a sample config for baseline tiffs # Remember, because it works as whitelist for each required tag we need an # entry here ##### # Required Baseline Tags ##### # 256 0100 ImageWidth The number of columns in the image, i.e., the number of pixels per row. 256; mandatory; range(1, 4294967295) # 257 0101 ImageLength The number of rows of pixels in the image. 257; mandatory; range(1, 4294967295) # 258 0102 BitsPerSample Number of bits per component. ##########################258; mandatory; logical_or(8,16) # Bitonal is optional, grey & RGB is mandatory. If 262 AND 258 exist, then the values need to be in the specified range. 258; optdepends(262.0); logical_or(1, 4, 8) 258; optdepends(262.1); logical_or(1, 4, 8) #258; depends(262.2); logical_or(ntupel(8,8,8), ntupel(16,16,16)) # TODO: this field allows a different number of bits per component for each component corresponding to a pixel. For example, RGB color data could use a different number of bits per component for each of the three color planes. 258; depends(262.2); logical_or(ntupel(8,8,8), ntupel(16,16,16)) 258; depends(262.3); logical_or(4, 8) 258; depends(262.8); only(8) # 259 0103 Compression Compression scheme used on the image data ### (1 means no compression) 259; mandatory; logical_or(1, 2, 3, 4, 5, 6, 32773) # 262 0106 PhotometricInterpretation The color space of the image data. ### 2 means RGB, 0 and 1 means bilevel or grayscale, 0 is unusual, 3 is Palette Color (NOT SUITABLE FOR LONG TERM PRESERVATION), 4 is Transparency Mask (NOT SUITABLE FOR LONG TERM PRESERVATION) 262; mandatory; logical_or(range(0, 6), only(8)) # 273 0111 StripOffsets For each strip, the byte offset of that strip. 273; mandatory; any # 277 0115 SamplesPerPixel The number of components per pixel. ### if RGB then 3 else 1 ### Even though Baseline TIFF allows for SamplesPerPixel>3, we do NOT allow this for long term archival. 277; depends(262.2); range(3, 10) 277; optdepends(262.1); only(1) 277; optdepends(262.0); only(1) # 278 0116 RowsPerStrip The number of rows per strip. 278; mandatory; range(1, 4294967295) # 279 0117 StripByteCounts For each strip, the number of bytes in the strip after compression. 279; mandatory; range(1, 4294967295) # 282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction. 282; mandatory; range(0, 4294967295) # 283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction. 283; mandatory; range(0, 4294967295) # 296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution. 1 = No absolute unit of measurement. 2 = Inch. 3 = Centimeter. Default: 2 296; mandatory; range(1, 3) ##### # optional fields ##### # NO OTHER VALUES FROM THE RANGE (0 - 7) ARE ALLOWED. ONLY "0" IS SUITABLE FOR LONG TERM ARCHIVAL. # 254 00FE NewSubfileType A general indication of the kind of data contained in this subfile. These values are defined as bit flags because they are independent of each other. Default is 0. 254; optional; range(0, 7) # DO NOT UNCOMMENT! THIS TAG IS DEPRECATED! USE NEW SUBFILE TYPE INSTEAD! # 255 00FF SubfileType A general indication of the kind of data contained in this subfile. This field is deprecated. The NewSubfileType field should be used instead. 255; optional; range(1, 3) # DO NOT UNCOMMENT! THRESHOLDING IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 263 0107 Threshholding For black and white TIFF files that represent shades of gray, the technique used to convert from gray to black and white pixels. Default is 1. 263; optional; range(1, 3) # DO NOT UNCOMMENT! CELL WIDTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 264 0108 CellWidth The width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. 264; depends(263.2); any # DO NOT UNCOMMENT! CELL LENGTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 265 0109 CellLength The length of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. This field should only be present if Threshholding = 2. 265; optdepends(263.2); any ### Support for FillOrder=2 is not required in a Baseline TIFF compliant reader. Default is 1. # 266 010A FillOrder The logical order of bits within a byte. 266; optional; logical_or(1, 2) # 269 010D Documentname 269; optional; regex("^[[:print:]]*$") # 270 010E ImageDescription A string that describes the subject of the image. 270; optional; regex("^[[:print:]]*$") # 271 010F Make The scanner manufacturer. 271; optional; regex("^[[:print:]]*$") # 272 0110 Model The scanner model name or number. 272; optional; regex("^[[:print:]]*$") # 274 0112 Orientation The orientation of the image with respect to the rows and columns. Default is 1, and only this value is Baseline TIFF conform. # THIS IS NOT BASELINE TIFF!!! 274; optional; range(1, 8) # 274; optional; only(1) # 280 0118 MinSampleValue The minimum component value used. Default is 0. 280; optional; range(0, 65534) # 281 0119 MaxSampleValue The maximum component value used; only for statistical purposes. Default is 2**(BitsPerSample) - 1. 281; optional; range(1, 65535) # 284 011C PlanarConfiguration How the components of each pixel are stored. 1 = Chunky format. 2 = Planar format (not recommended for general interchange) and Baseline TIFF readers are not required to support it. Default: 1. # If SamplesPerPixel is 1, PlanarConfiguration is irrelevant, and need not be included. 284; optional; logical_or(1, 2) # 285 011D PageName The name of the page from which this image was scanned. 285; optional; regex("^[[:print:]]*$") # 286 011E XPosition The X offset in ResolutionUnits of the left side of the image, with respect to the left side of the page. 285; optional; any # 287 011F YPosition The Y offset in ResolutionUnits of the top of the image, with respect to the top of the page. In the TIFF coordinate scheme, the positive Y direction is down, so that YPosition is always positive. 285; optional; any # FREE OFFSETS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 288 0120 FreeOffsets For each string of contiguous unused bytes in a TIFF file, the byte offset of the string. Not recommended for general interchange. 288; optional; any # FREE BYTE COUNTS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 289 0121 FreeByteCounts For each string of contiguous unused bytes in a TIFF file, the number of bytes in the string. Not recommended for general interchange. 289; optional; any # 290 0122 GrayResponseUnit The precision of the information contained in the GrayResponseCurve. Default: 2; Recommended: 3 290; optdepends(262.0); range(1, 5) 290; optdepends(262.1); range(1, 5) # 291 0123 GrayResponseCurve For grayscale data, the optical density of each possible pixel value. 291; optdepends(262.0); any 291; optdepends(262.1); any # 292 0124 T4Options Option flags for T4 compression. Default: 0 291; optdepends(259.3); range(0, 4294967296) # 293 0125 T6Options Option flags for T4 compression. Default: 0 291; optdepends(259.4); range(0, 4294967296) # 297 PageNumber actual page, and total pagecount, the actual page count starts with 0; Recommended: 0, 1 # 297; optional; ntupel(0,1) 297; optional; any # 301 012D TransferFunction Describes a transfer function for the image in tabular style. 301; optdepends(262.2); any # 305 0131 Software Name and version number of the software package(s) used to create the image. 305; optional; regex("^[[:print:]]*$") # 306 0132 DateTime Date and time of image creation in the format "YYYY:MM:DD HH:MM:SS". 306; optional; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") # ARTIST IS NOT SUITABLE FOR LONG TERM ARCHIVAL DUE TO PRIVACY CONCERNS! # 315 013B Artist Person who created the image. Some older TIFF files used this tag for storing Copyright information. 315; optional; regex("^[[:print:]]*$") # HOST COMPUTER INFORMATION IS NOT SUITABLE AND IRRELEVANT FOR LONG TERM ARCHIVAL! # 316 013C HostComputer The computer and/or operating system in use at the time of image creation. 316; optional; regex("^[[:print:]]*$") # 317 013D Predictor A predictor is a mathematical operator that is applied to the image data before an encoding scheme is applied. Currently this field is used only with LZW. Default: 1 316; optdepends(259.5); logical_or(1, 2) # WhitePoint, if RGB, points to chromaticity of the white point of the image.This is the chromaticity # when each of the primaries has its ReferenceWhite value. The value is described using the 1931 CIE # xy chromaticity diagram and only the chromaticity is specified. This value can correspond to the # chromaticity of the alignment white of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. The ordering is white[x], white[y]. # (Source: www.awaresystems.be) # example: CIE Standard Illuminant D65 used by CCIR Recommendation 709 and Kodak PhotoYCC is: # 3127/10000,3290/10000 318; optdepends(262.2); any # PrimaryChromaticities, This is the chromaticity for each of the primaries when it has its ReferenceWhite # value and the other primaries have their ReferenceBlack values. These values are described using the # 1931 CIE xy chromaticity diagram and only the chromaticities are specified. These values can correspond # to the chromaticities of the phosphors of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. # (Source: www.awaresystems.be) # The ordering is red[x], red[y], green[x], green[y], blue[x], and blue[y]. # For example the CCIR Recommendation 709 primaries are: # 640/1000,330/1000, # 300/1000, 600/1000, # 150/1000, 60/1000 319; optdepends(262.2); any # COLOR MAP TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 320 0140 ColorMap This field defines a Red-Green-Blue color map (often called a lookup table) for palette color images. 320; optional; any # 321 0141 HalftoneHints The purpose of the HalftoneHints field is to convey to the halftone function the range of gray levels within a colorimetrically-specified image that should retain tonal detail. 321; optional; any # 322 0142 TileWidth The tile width in pixels. This is the number of columns in each tile. Must be a multiple of 16. 322; optional; range(16, 4294967296) # 323 0143 TileLength The tile length (height) in pixels. This is the number of rows in each tile. Must be a multiple of 16. 323; optional; range(16, 4294967296) # 324 0144 TileOffsets For each tile, the byte offset of that tile, as compressed and stored on disk. 324; optional; range(1, 4294967296) # 325 0145 TileByteCounts For each tile, the number of (compressed) bytes in that tile. 325; optional; range(1, 4294967296) # 332 014C InkSet The set of inks used in a separated (PhotometricInterpretation=5) image. Default: 1 332; optdepends(262.5); logical_or(1, 2) # 333 014D InkNames The name of each ink used in a separated (PhotometricInterpretation=5) image, written as a list of concatenated, NUL-terminated ASCII strings. 333; optdepends(262.5); regex("^[[:print:]]*$") # 334 014E NumberOfInks The number of inks. Usually equal to SamplesPerPixel, unless there are extra samples. Default: 4 334; optional; range(1, 10) # 336 0150 DotRange The component values that correspond to a 0% dot and 100% dot. DotRange[0] corresponds to a 0% dot, and DotRange[1] corresponds to a 100% dot. 336; optional; any # 337 0151 TargetPrinter A description of the printing environment for which this separation is intended. 337; optional; regex("^[[:print:]]*$") # EXTRA SAMPLES TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL BECAUSE THEIR MEANING CANNOT BE DOCUMENTED! # 338 0152 ExtraSamples Description of extra components. 338; optional; range(0, 2) # 339 0153 SampleFormat This field specifies how to interpret each data sample in a pixel. Default: 1 339; optional; range(1, 4) # 340 0154 SMinSampleValue This field specifies the minimum sample value. 340; optional; any # 341 0155 SMaxSampleValue This field specifies the maximum sample value. 341; optional; any # 342 0156 TransferRange Expands the range of the TransferFunction. 342; optdepends(262.2); any # 512 0200 JPEGProc This Field indicates the JPEG process used to produce the compressed data. 512; depends(259.6); logical_or(1, 14) # 513 0201 JPEGInterchangeFormat This Field indicates whether a JPEG interchange format bitstream is present in the TIFF file. 513; optdepends(259.6); any # 514 0202 JPEGInterchangeFormatLength This Field indicates the length in bytes of the JPEG interchange format bitstream. 514; optdepends(259.6); any # 515 0203 JPEGRestartInterval This Field indicates the length of the restart interval used in the compressed image data. 515; optdepends(259.6); any # 517 0205 JPEGLosslessPredictors This Field points to a list of lossless predictor-selection values, one per component. 517; optdepends(259.6); range(1, 7) # 517 0205 JPEGPointTransforms This Field points to a list of point transform values, one per component. 517; optdepends(259.6); any # 519 0207 JPEGQTables This Field points to a list of offsets to the quantization tables, one per component. 519; optdepends(259.6); any # 520 0208 JPEGDCTables This Field points to a list of offsets to the DC Huffman tables or the lossless Huffman tables, one per component. 520; optdepends(259.6); any # 521 0209 JPEGACTables This Field points to a list of offsets to the Huffman AC tables, one per component. 521; optdepends(259.6); any # 529 0211 YCbCrCoefficients The transformation from RGB to YCbCr image data. 529; optdepends(262.6); any # 530 0212 YCbCrSubSampling Specifies the subsampling factors used for the chrominance components of a YCbCr image. The default values of this field are [ 2, 2 ]. #530; optdepends(262.6); logical_or(ntupel(1,1),ntupel(1,2),ntupel(1,4),ntupel(2,1),ntupel(2,2),ntupel(2,4),ntupel(4,1),ntupel(4,2),ntupel(4,4)) 530; optdepends(262.6); any # 531 0213 YCbCrPositioning Specifies the positioning of subsampled chrominance components relative to luminance samples. 531; optdepends(262.6); any # 532 0214 ReferenceBlackWhite Specifies a pair of headroom and footroom image data values (codes) for each pixel component. 532; optdepends(262.2); any # 700 02BC XMP XML packet containing XMP metadata. 700; optional; any # 33432 8298 Copyright Complete copyright notice of the person or organization that claims the copyright to the image. 33432; optional; regex("^[[:print:]]*$") # IPTC METADATA ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 33723 83BB IPTC IPTC (International Press Telecommunications Council) metadata. # http://www.iptc.org/download/download.php?fn=IIMV4.1.pdf 33723; optional; any # PHOTOSHOP METADATA ARE PROPRIETARY AND HENCE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 34377 8649 Photoshop Collection of Photoshop 'Image Resource Blocks'. 34377; optional; any # 34665 8769 Exif IFD A pointer to the Exif IFD. Exif IFD is a set of tags for recording Exif-specific attribute information. It is pointed to by the offset from the TIFF header (Value Offset) indicated by an Exif private tag value. An Exif IFD has the same structure as that of the IFD specified in TIFF. Ordinarily, however, it does not contain image data as in the case of TIFF. 34665; optional; any # 34675 8773 ICC Profile ICC Profile data 34675; optional; any checkit_tiff-0.4.2/example_configs/cit_tiff6_geotiff_SLUB.cfg000066400000000000000000000251451327425157300242100ustar00rootroot00000000000000# tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) | optdepends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # This defines a sample config for baseline tiffs # Remember, because it works as whitelist for each required tag we need an # entry here mode(baseline) mode(enable_type_checks) mode(enable_offset_checks) mode(enable_ifd_checks) ##### # Required Baseline Tags ##### # 256 0100 ImageWidth The number of columns in the image, i.e., the number of pixels per row. 256; mandatory; range(1, 4294967295) # 257 0101 ImageLength The number of rows of pixels in the image. 257; mandatory; range(1, 4294967295) # 258 0102 BitsPerSample Number of bits per component. ##########################258; mandatory; logical_or(8,16) # Bitonal is optional, grey & RGB is mandatory. If 262 AND 258 exist, then the values need to be in the specified range. 258; optdepends(262.0); logical_or(1, 4, 8) 258; optdepends(262.1); logical_or(1, 4, 8) 258; depends(262.2); logical_or(ntupel(8,8,8), ntupel(16,16,16)) 258; depends(262.3); logical_or(4, 8) # 259 0103 Compression Compression scheme used on the image data ### (1 means no compression) 259; mandatory; only(1) # 262 0106 PhotometricInterpretation The color space of the image data. ### 2 means RGB, 0 and 1 means bilevel or grayscale, 0 is unusual, 3 is Palette Color (FORBIDDEN), 4 is Transparency Mask (FORBIDDEN) 262; mandatory; range(0, 2) # 273 0111 StripOffsets For each strip, the byte offset of that strip. 273; mandatory; any # 277 0115 SamplesPerPixel The number of components per pixel. ### if RGB then 3 else 1 ### Even though Baseline TIFF allows for SamplesPerPixel>3, we do NOT allow this for long term archival. 277; depends(262.2); only(3) 277; optdepends(262.1); only(1) 277; optdepends(262.0); only(1) # 278 0116 RowsPerStrip The number of rows per strip. 278; mandatory; range(1, 4294967295) # 279 0117 StripByteCounts For each strip, the number of bytes in the strip after compression. # Hint: Because value could be an array, only "any" is used 279; mandatory; any # 282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction. 282; mandatory; range(300, 4000) # 283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction. 283; mandatory; range(300, 4000) # 296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution. 1 = No absolute unit of measurement. 2 = Inch. 3 = Centimeter. Default: 2 296; mandatory; only(2) ##### # optional fields ##### # NO OTHER VALUES FROM THE RANGE (0 - 7) ARE ALLOWED. ONLY "0" IS SUITABLE FOR LONG TERM ARCHIVAL. # 254 00FE NewSubfileType A general indication of the kind of data contained in this subfile. These values are defined as bit flags because they are independent of each other. Default is 0. 254; optional; logical_or(0, 2) # DO NOT UNCOMMENT! THIS TAG IS DEPRECATED! USE NEW SUBFILE TYPE INSTEAD! # 255 00FF SubfileType A general indication of the kind of data contained in this subfile. This field is deprecated. The NewSubfileType field should be used instead. #255; optional; range(1, 3) # DO NOT UNCOMMENT! THRESHOLDING IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 263 0107 Threshholding For black and white TIFF files that represent shades of gray, the technique used to convert from gray to black and white pixels. Default is 1. #263; optional; range(1, 3) # DO NOT UNCOMMENT! CELL WIDTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 264 0108 CellWidth The width of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. #264; depends(263.2); any # DO NOT UNCOMMENT! CELL LENGTH IS NOT SUITABLE FOR LONG TERM ARCHIVAL! # 265 0109 CellLength The length of the dithering or halftoning matrix used to create a dithered or halftoned bilevel file. This field should only be present if Threshholding = 2. #265; depends(263.2); any ### Support for FillOrder=2 is not required in a Baseline TIFF compliant reader. Default is 1. # 266 010A FillOrder The logical order of bits within a byte. 266; optional; only(1) # 269 010D Documentname 269; optional; printascii # 270 010E ImageDescription A string that describes the subject of the image. 270; optional; regex("^[[:print:]]*$") # 271 010F Make The scanner manufacturer. 271; optional; regex("^[[:print:]]*$") # 272 0110 Model The scanner model name or number. 272; optional; regex("^[[:print:]]*$") # 274 0112 Orientation The orientation of the image with respect to the rows and columns. Default is 1, and only this value is Baseline TIFF conform. # 274; optional; range(1, 8) # THIS IS NOT BASELINE TIFF!!! DO NOT UNCOMMENT!!! 274; optional; only(1) # 280 0118 MinSampleValue The minimum component value used. Default is 0. 280; optional; any # 281 0119 MaxSampleValue The maximum component value used; only for statistical purposes. Default is 2**(BitsPerSample) - 1. 281; optional; any # 284 011C PlanarConfiguration How the components of each pixel are stored. 1 = Chunky format. 2 = Planar format and Baseline TIFF readers are not required to support it. Default: 1. 284; optional; only(1) # DO NOT UNCOMMENT! FREE OFFSETS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 288 0120 FreeOffsets For each string of contiguous unused bytes in a TIFF file, the byte offset of the string. Not recommended for general interchange. #288; optional; any # DO NOT UNCOMMENT! FREE BYTE COUNTS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 289 0121 FreeByteCounts For each string of contiguous unused bytes in a TIFF file, the number of bytes in the string. Not recommended for general interchange. #289; optional; any # 290 0122 GrayResponseUnit The precision of the information contained in the GrayResponseCurve. Default: 2; Recommended: 3 290; optdepends(262.0); range(1, 5) 290; optdepends(262.1); range(1, 5) # 291 0123 GrayResponseCurve For grayscale data, the optical density of each possible pixel value. 291; optdepends(262.0); any 291; optdepends(262.1); any # 297 PageNumber actual page, and total pagecount, the actual page count starts with 0; Recommended: 0, 1 297; optional; ntupel(0,1) # 305 0131 Software Name and version number of the software package(s) used to create the image. 305; optional; regex("^[[:print:]]*$") # 306 0132 DateTime Date and time of image creation in the format "YYYY:MM:DD HH:MM:SS". #306; optional; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") 306; optional; datetime # DO NOT UNCOMMENT! ARTIST IS NOT SUITABLE FOR LONG TERM ARCHIVAL DUE TO PRIVACY CONCERNS! # 315 013B Artist Person who created the image. Some older TIFF files used this tag for storing Copyright information. #315; optional; any # DO NOT UNCOMMENT! HOST COMPUTER INFORMATION IS NOT SUITABLE AND IRRELEVANT FOR LONG TERM ARCHIVAL! # 316 013C HostComputer The computer and/or operating system in use at the time of image creation. #316; optional; any # WhitePoint, if RGB, points to chromaticity of the white point of the image.This is the chromaticity # when each of the primaries has its ReferenceWhite value. The value is described using the 1931 CIE # xy chromaticity diagram and only the chromaticity is specified. This value can correspond to the # chromaticity of the alignment white of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. The ordering is white[x], white[y]. # (Source: www.awaresystems.be) # example: CIE Standard Illuminant D65 used by CCIR Recommendation 709 and Kodak PhotoYCC is: # 3127/10000,3290/10000 318; optional; any # PrimaryChromaticities, This is the chromaticity for each of the primaries when it has its ReferenceWhite # value and the other primaries have their ReferenceBlack values. These values are described using the # 1931 CIE xy chromaticity diagram and only the chromaticities are specified. These values can correspond # to the chromaticities of the phosphors of a monitor, the filter set and light source combination of a # scanner or the imaging model of a rendering package. # (Source: www.awaresystems.be) # The ordering is red[x], red[y], green[x], green[y], blue[x], and blue[y]. # For example the CCIR Recommendation 709 primaries are: # 640/1000,330/1000, # 300/1000, 600/1000, # 150/1000, 60/1000 319; optional; any # DO NOT UNCOMMENT! COLOR MAP TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 320 0140 ColorMap This field defines a Red-Green-Blue color map (often called a lookup table) for palette color images. #320; optional; any # DO NOT UNCOMMENT! EXTRA SAMPLES TIFFS ARE NOT SUITABLE FOR LONG TERM ARCHIVAL BECAUSE THEIR MEANING CANNOT BE DOCUMENTED! # 338 0152 ExtraSamples Description of extra components. #338; optional; range(0-2) # 700 02BC XMP XML packet containing XMP metadata. 700; optional; any # 33432 8298 Copyright Complete copyright notice of the person or organization that claims the copyright to the image. 33432; optional; regex("^[[:print:]]*$") # DO NOT UNCOMMENT! IPTC METADATA ARE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 33723 83BB IPTC IPTC (International Press Telecommunications Council) metadata. # http://www.iptc.org/download/download.php?fn=IIMV4.1.pdf #33723; optional; any # DO NOT UNCOMMENT! PHOTOSHOP METADATA ARE PROPRIETARY AND HENCE NOT SUITABLE FOR LONG TERM ARCHIVAL! # 34377 8649 Photoshop Collection of Photoshop 'Image Resource Blocks'. #34377; optional; any # 34665 8769 Exif IFD A pointer to the Exif IFD. Exif IFD is a set of tags for recording Exif-specific attribute information. It is pointed to by the offset from the TIFF header (Value Offset) indicated by an Exif private tag value. An Exif IFD has the same structure as that of the IFD specified in TIFF. Ordinarily, however, it does not contain image data as in the case of TIFF. 34665; optional; any # 34675 8773 ICC Profile ICC Profile data. Mandatory for RGB 8-Bit/16-Bit, Optional for Grayscale 34675; optdepends(262.0); iccprofile 34675; optdepends(262.1); iccprofile 34675; optdepends(262.2); iccprofile #GeoTiff Data # 33550 GeoTIFF ModelPixelScaleTag 33550; mandatory; any # 33922 ModelTiepointTag 33922; mandatory; any # 34264 ModelTransformationTag -> must not exist next to 33550 ModelPixelScaleTag #34264; mandatory; any # 34735 Geotiff GeoKeyDirectoryTag 34735; mandatory; any # 34736 Geotiff GeoDoubleParamsTag 34736; mandatory; any # 34737 GeoAsciiParamsTag 34737; mandatory; any # 34853 GPS IFD 34853; optional; any # 42112 GDAL Metadata 42112; optional; any # 42113 GDAL_NODATA -> must not exist since software interprete this as transparency, which is not allowed #42113; optional; any #Georeferenced Additional Tags # Testing lfulg-geo-data # 339 SampleFormat 339; optional; any checkit_tiff-0.4.2/example_configs/cit_tiff_baseline_minimal.cfg000066400000000000000000000063571327425157300251460ustar00rootroot00000000000000# tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # This defines a sample config for baseline tiffs # Remember, because it works as whitelist for each required tag we need an # entry here # Required Baseline Tags # 254 00fe NewSubfileType A general indication of the kind of data contained in this subfile. ### could be part of baseline TIFF, but value could only be 0, because whether ### another image is contained (bit 0), nor is it a multipage TIFF (bit 2), nor ### it is a transparency mask (bit 3), because baseline does not allow multiple ### IFDs 254; optional; logical_or(0, 2) # 256 0100 ImageWidth The number of columns in the image, i.e., the number of pixels per row. 256; mandatory; any # 257 0101 ImageLength The number of rows of pixels in the image. 257; mandatory; any # 258 0102 BitsPerSample Number of bits per component. ### black/white ### grayscale 258; depends(262.0); logical_or(1,4,8) 258; depends(262.1); logical_or(1,4,8) ### colormap 258; depends(320.any); logical_or(4,8) ### RGB 258; depends(262.2); logical_or(ntupel(8,8,8),ntupel(16,16,16)) # 259 0103 Compression Compression scheme used on the image data ### (1 means no compression, 2 CCIT Group 3, 32773 PackBits) ### black/white (BitsPerSample is optional for b/w) 259; depends(262.0); logical_or(1,2,32773) 259; depends(262.1); logical_or(1,2,32773) ### grayscale (BitsPerSample must exist) 259; depends(258.4); logical_or(1,32773) 259; depends(258.8); logical_or(1,32773) ### colormap 259; depends(262.3); logical_or(1,32773) ### RGB 259; depends(262.2); logical_or(1,32773) # 262 0106 PhotometricInterpretation The color space of the image data. ### 2 means RGB, 0 and 1 means bilevel or grayscale, 0 is unusual, 3 colormap 262; mandatory; logical_or(0,1,2) # TODO: needs checks in code 262; depends(320.any); only(3) # 273 0111 StripOffsets For each strip, the byte offset of that strip. 273; mandatory; any # 274 0112 Orientation The orientation of the image with respect to the rows and columns 274; optional; only(1) # 277 0115 SamplesPerPixel The number of components per pixel. ### if RGB then 3 else 1 277; depends(262.2); only(3) 277; depends(262.3); only(1) 277; depends(262.1); only(1) 277; depends(262.0); only(1) # 278 0116 RowsPerStrip The number of rows per strip. 278; mandatory; any # 279 0117 StripByteCounts For each strip, the number of bytes in the strip after compression. 279; mandatory; any # 282 011A XResolution The number of pixels per ResolutionUnit in the ImageWidth direction. 282; mandatory; any # 283 011B YResolution The number of pixels per ResolutionUnit in the ImageLength direction. 283; mandatory; any # 284 011C PlanarConfiguration If 2 then Bitplanes used, if 1 chunks used, only for RGB relevant ### for baseline only value 1 allowed and only if SamplesPerPixel = 3 ### for samplesperpixel == 1, the value is irrelevant 284; optdepends(277.3); only(1) 284; optdepends(277.1); range(1,2) # 296 0128 ResolutionUnit The unit of measurement for XResolution and YResolution. ### (2 means inch) 296; optional; logical_or(1,2,3) # 320 ColorMap, only for paletted 320; optional; any checkit_tiff-0.4.2/example_configs/cit_tiff_ep.cfg000066400000000000000000000133651327425157300222570ustar00rootroot00000000000000# This defines a sample config for baseline TIFFs with TIFF/EP extensions, # based on ISO 12234-2:2001 # HINT: because checkit_tiff is designed as a *baseline TIFF* validation tool, # some rules could not be defined to allow a fine granular validation of # TIFF/EP files! # tag; required; values # # works as whitelist # * tag: any tag number in TIFF # * required: mandatory | optional | depends( $tag.$value ) | optdepends( $tag.$value ) # * values: range($start, $end) | logical_or( $a, …) | only($a) |any # Remember, because it works as whitelist for each required tag we need an # entry here # 5.2.1 TIFF/EPStandard ID, should have 4 bytes: 1 0 0 0 37398; mandatory; only(1) # 5.2.2 ImageWidth (depends if Thumbnail or Main, on Thumbnail only 0..256 allowed 256; mandatory; any # 5.2.3 ImageLength (depends if Thumbnail or Main, on Thumbnail only 0..256 allowed 257; mandatory; any # 5.2.4 NewSubFileType, Bit 0 = 1 if thumbnail else 0 254; mandatory; any # 5.2.5 SubIFDs 330; mandatory; any # 5.2.6 XResolution 282; mandatory; any # 5.2.7 YResolution 283; mandatory; any # 5.2.8 ResolutionUnit 284; mandatory; range(1,3) # 5.2.9 FocalPlaneXResolution 37390; optional; any # 5.2.10 FocalPlaneYResolution 37391; optional; any # 5.2.11 FocalPlaneResolutionUnit 37392; optional; range(1,5) # 5.2.12 Orientation 274; optional; logical_or(1, 3, 6, 8, 9) # 5.2.13 Photometric Interpretation 262; mandatory; logical_or(1, 2, 6, 32803, range(32768, 65535)) # 5.2.14 Planar Configuration 284; mandatory; range(1,2) # 5.2.15 Interlace, optional tag indicates the field number of multifield images 34857; optional; range(0, 16383) # 5.2.16 Sensing Method, type of image sensor 37399; mandatory; range(0,8) # 5.2.17 CFARepeatPatternDim, mandatory if PhotometricInterpretation=32803, # optional if PhotometricInterpretation=2|6 && SensingMethod=2 33421; depends(262.32803); range(0,1) 33421; optdepends(37399.2); range(0,1) # 5.2.18 CFAPattern, mandatory if PhotometricInterpretation=32803, # optional if PhotometricInterpretation=2|6 && SensingMethod=2 33422; depends(262.32803); any 33422; optdepends(37399.2); any # 5.2.19 SamplesPerPixel 277; depends(262.range(32768,65535)); any 277; depends(262.1); only(1) 277; depends(262.32803); only(1) 277; depends(262.2); only(3) 277; depends(262.6); only(3) # 5.2.20 BitsPerSample 258; mandatory; range(0, 65535) # 5.2.21 StripOffsets, it is only mandatory if no Tiles used. 273; mandatory; any # 5.2.22 RowsPerStrip 278; depends(273.any); any # 5.2.23 StripByteCounts 279; depends(273.any); any # 5.2.24 TileWidth, it is only mandatory if no Strips used. #322; mandatory; any # 5.2.25 TileLength 323; depends(322.any); any # 5.2.26 TileOffsets 324; depends(322.any); any # 5.2.27 TileByteCounts 325; depends(322.any); any # 5.2.28 Compression 259; mandatory; logical_or(1, 7, range(32768,65535)) # 5.2.29 CompressedBitsPerPixel 37122; optional; any # 5.2.30 JPEGTables 347; optional; any # 5.2.31 YCbCrSubSampling (two values, both are 1,2 or 4) 347; depends(262.6); any # 5.2.32 YCbCrPositioning 531; depends(262.6); only(2) # 5.2.33 YCbCrCoefficents 529; depends(262.6); any # 5.2.34 ReferenceBlackWhite 532; depends(262.6); any # 5.2.35 Make 271; mandatory; any # 5.2.36 Model 272; mandatory; any # 5.2.37 Software 305; mandatory; any # 5.2.38 ImageNumber 37393; optional; any # 5.2.39 Image Description 270; mandatory; any # 5.2.40 Artist 315; optional; any # 5.2.41 Copyright 33432; mandatory; any # 5.2.42 ImageHistory 37395; optional; any # 5.2.43 IPTC/NAA 33723; optional; any # 5.2.44 SecurityClassification 37394; optional; any # 5.2.45 GPSInfo 34853; optional; any # 5.2.46 DateTimeOriginal, mandatory here as part of IFD0 (in opposite to EXIF # DateTimeOriginal which is referenced by EXIF IFD) 36867; mandatory; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") # 5.2.47 DateTime, mandatory 306; mandatory; regex("^[12][901][0-9][0-9]:[01][0-9]:[0-3][0-9] [012][0-9]:[0-5][0-9]:[0-6][0-9]$") # 5.2.48 TimeZoneOffset 34858; optional; any # 5.2.49 ExposureTime 33434; optional; any # 5.2.50 ShutterSpeedValue 37377; optional; any # 5.2.51 FNumber encodes lens f-number 33437; optional; any # 5.2.52 ApertureValue 37378; optional; any # 5.2.53 MaxApertureValue 37381; optional; any # 5.2.54 BrightnessValue 37379; optional; any # 5.2.55 ExposureBiasValue 37380; optional; any # 5.2.56 Exposure Program 34850; optional; logical_or(range(0, 8), range(32768,65535)) # 5.2.57 Metering Mode 37383; optional; logical_or(range(0,4), range(32768, 65535)) # 5.2.58 Flash, Bitflags encoded # 0b---- ---- ---- ---0 # 0b---- ---- ---- ---1 fire status # 0b---- ---- ---- -00- # 0b---- ---- ---- -10- # 0b---- ---- ---- -11- return sense (01 reserved) # 0b---- ---- ---0 0--- # 0b---- ---- ---0 1--- # 0b---- ---- ---1 0--- # 0b---- ---- ---1 1--- mode bits # 0b---- ---- --0- ---- # 0b---- ---- --1- ---- unit present # 0b0000 0000 00-- ---- reserved 37385; optional; logical_or(0,1,5,7,9,13,15,16,24,25,29,31,32) # 5.2.59 FlashEnergy 37387; optional; any # 5.2.60 FocalLength 37386; optional; any # 5.2.61 SubjectDistance 37382; optional; any # 5.2.62 SubjectLocation 37396; optional; any # 5.2.63 SelfTimerMode 34859; optional; range(0, 65535) # 5.2.64 BatteryLevel 33423; optional; any # 5.2.65 LightSource 37384; optional; any # 5.2.66 InterColourProfile (it is not defined as optional here, mandatory?) 34675; mandatory; any # 5.2.67 ExposureIndex 37397; optional; any # 5.2.68 ISOSpeedRatings 34855; optional; any # 5.2.69 OECF (optp-electorinc conversion function) 34856; optional; any # 5.2.70 SpectralSensitivity 34852; optional; any # 5.2.71 SpatialFrequencyResponse 37388; optional; any # 5.2.72 Noise (optional, because "The camera's 'noise' level may be recorded in the Noise tag-field" 37389; optional; any checkit_tiff-0.4.2/grammar.xhtml000066400000000000000000004404061327425157300166640ustar00rootroot00000000000000 start: Line EndOfFile start ::= Line+ EndOfFile no referencesLine: CommentLine SpaceLine ModeLine IncludeLine TagLine EndOfLine MiscUntilEOL Line ::= ( CommentLine | SpaceLine | ModeLine | IncludeLine | TagLine ) EndOfLine | MiscUntilEOL referenced by: start ModeLine: mode ( Mode ) ModeLine ::= 'mode' ( '(' ( Mode ')'? )? )? referenced by: Line LogicalOr: logical_or ( LogicalOrList ) LogicalOr ::= 'logical_or' '(' LogicalOrList ')' referenced by: Content LogicalOrListElement: any Range Only Number NTupel RegEx printascii MiscUntilEOL LogicalOrListElement ::= 'any' | Range | Only | Number | NTupel | RegEx | 'printascii' | MiscUntilEOL referenced by: LogicalOrList LogicalOrList: LogicalOrListElement Colon LogicalOrList ::= LogicalOrListElement ( Colon LogicalOrListElement )* referenced by: LogicalOr Mode: baseline enable_type_checks enable_offset_checks enable_ifd_checks enhanced MiscUntilEOL Mode ::= 'baseline' | 'enable_type_checks' | 'enable_offset_checks' | 'enable_ifd_checks' | 'enhanced' | MiscUntilEOL referenced by: ModeLine TagLine: Tag Semicolon Requirements Semicolon Content TagLine ::= Tag ( Semicolon ( Requirements ( Semicolon Content? )? )? )? referenced by: Line Tag: Number Tag ::= Number referenced by: TagLine TagReference: Number MiscUntilEOL TagReference ::= Number | MiscUntilEOL referenced by: IfDepends OptDepends Semicolon: ; Space MiscUntilEOL Semicolon ::= ';' Space* | MiscUntilEOL referenced by: TagLine Requirements: mandatory IfDepends OptDepends optional MiscUntilEOL Requirements ::= 'mandatory' | IfDepends | OptDepends | 'optional' | MiscUntilEOL referenced by: TagLine IfDepends: depends ( TagReference Dot ValueReference ) IfDepends ::= 'depends' ( '(' ( TagReference ( Dot ( ValueReference ')'? )? )? )? )? referenced by: Requirements OptDepends: optdepends ( TagReference Dot ValueReference ) OptDepends ::= 'optdepends' ( '(' ( TagReference ( Dot ( ValueReference ')'? )? )? )? )? referenced by: Requirements Content: any Range LogicalOr Only NTupel RegEx printascii datetime iccprofile MiscUntilEOL Content ::= 'any' | Range | LogicalOr | Only | NTupel | RegEx | 'printascii' | 'datetime' | 'iccprofile' | MiscUntilEOL referenced by: TagLine Range: range ( Number Colon Number ) Range ::= 'range' ( '(' ( Number ( Colon ( Number ')'? )? )? )? )? referenced by: Content LogicalOrListElement ValueReference Colon: , Space MiscUntilEOL Colon ::= ',' Space* | MiscUntilEOL referenced by: LogicalOrList Range ValueList Dot: . Space MiscUntilEOL Dot ::= '.' Space* | MiscUntilEOL referenced by: IfDepends OptDepends ValueList: Value Colon ValueList ::= Value ( Colon Value )* referenced by: NTupel Value: Number Value ::= Number referenced by: ValueList NTupel: ntupel ( ValueList ) NTupel ::= 'ntupel' ( '(' ( ValueList ')'? )? )? referenced by: Content LogicalOrListElement ValueReference ValueReference: any Number RegEx Range NTupel Only MiscUntilEOL ValueReference ::= 'any' | Number | RegEx | Range | NTupel | Only | MiscUntilEOL referenced by: IfDepends OptDepends Only: only ( Number ) Only ::= 'only' ( '(' ( Number ')'? )? )? referenced by: Content LogicalOrListElement ValueReference RegEx: regex ( " PCRE " ) RegEx ::= 'regex' ( '(' ( '"' PCRE* ( '"' ')'? )? )? )? referenced by: Content LogicalOrListElement ValueReference SpaceLine: Space SpaceLine ::= Space* referenced by: Line EndOfFile: EndOfFile ::= referenced by: start EscapedPCRE: \ \ " EscapedPCRE ::= '\' ( '\' | '"' ) referenced by: PCRE CommentLine: # . - EndOfLine CommentLine ::= '#' ( . - EndOfLine )* referenced by: Line IncludeLine: include ( [A-Z] [a-z] [0-9] _ . / [#x002D] ) IncludeLine ::= 'include' '(' [A-Za-z0-9_./#x002D]+ ')' referenced by: Line Number: 0x [0-9] [a-f] 2^ Digit Number ::= '0x' [0-9a-f]+ | '2^'? Digit+ referenced by: LogicalOrListElement Only Range Tag TagReference Value ValueReference Space: [#x0009] Space ::= [ #x0009] referenced by: Colon Dot Semicolon SpaceLine Digit: [0-9] Digit ::= [0-9] referenced by: Number EndOfLine: [#x000D] [#x000A] EndOfLine ::= [#x000D#x000A] referenced by: CommentLine Line MiscUntilEOL: [^#x000D#x000A] MiscUntilEOL ::= [^#x000D#x000A]+ referenced by: Colon Content Dot Line LogicalOrListElement Mode Requirements Semicolon TagReference ValueReference PCRE: EscapedPCRE [^"\] PCRE ::= EscapedPCRE | [^"\] referenced by: RegEx   ... generated by Railroad Diagram Generator R R checkit_tiff-0.4.2/src/000077500000000000000000000000001327425157300147375ustar00rootroot00000000000000checkit_tiff-0.4.2/src/CMakeLists.txt000066400000000000000000000075601327425157300175070ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.6) project (checkit_tiff) include_directories("${PROJECT_SOURCE_DIR}/headers") include_directories("${PROJECT_SOURCE_DIR}/validate_icc") include (CheckSymbolExists) include (CheckFunctionExists) file( GLOB checkit_tiff_SOURCES "${PROJECT_SOURCE_DIR}/tagrules/*.c" "${PROJECT_SOURCE_DIR}/ifdrules/*.c" "${PROJECT_SOURCE_DIR}/messages/*.c" "${PROJECT_SOURCE_DIR}/helper/*.c" "${PROJECT_SOURCE_DIR}/helper/renderer/*.c" "${PROJECT_SOURCE_DIR}/parser/*parser.c" "${PROJECT_SOURCE_DIR}/validate_icc/*.c" "${PROJECT_SOURCE_DIR}/risk_analyzer/*.c" ) file( GLOB checkit_tiff_risk_SOURCES "${PROJECT_SOURCE_DIR}/helper/check_helper.c" "${PROJECT_SOURCE_DIR}/helper/check_print.c" "${PROJECT_SOURCE_DIR}/helper/check_tiffparse.c" "${PROJECT_SOURCE_DIR}/messages/*.c" "${PROJECT_SOURCE_DIR}/risk_analyzer/*.c" ) # # Make a version file containing the current version from git. # execute_process( COMMAND git rev-list HEAD --count OUTPUT_VARIABLE REPO_REVISION OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process( COMMAND git rev-parse --abbrev-ref HEAD OUTPUT_VARIABLE BUILD_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND git describe --tags OUTPUT_VARIABLE BUILD_TAG OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND git rev-parse HEAD OUTPUT_VARIABLE BUILD_REV_ID OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process( COMMAND git describe --long --tags --dirty --always OUTPUT_VARIABLE BUILD_REV_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE) add_definitions(-DVERSION="${BUILD_BRANCH}_${BUILD_TAG}") add_definitions(-DREPO_REVISION="${REPO_REVISION}") # Check for compatibility with gnu11 # Compile with gnu11 support. include(CheckCCompilerFlag) CHECK_C_COMPILER_FLAG("-std=gnu11" COMPILER_SUPPORTS_GNU11) if(COMPILER_SUPPORTS_GNU11) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") else() message(STATUS "Your compiler (${CMAKE_C_COMPILER}) has no gnu11 support. If you are using clang on Apple OS X, please switch to gcc (version > 4.7) which is compliant with the C11 standard.") endif() if(WIN32) add_definitions(-D__WIN32__=1) SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") SET(BUILD_SHARED_LIBRARIES OFF) # needed to increase default stack, because Win7 has only 1MB SET(CMAKE_EXE_LINKER_FLAGS "-static -Wl,--stack,20000000") add_definitions(-DPCRE_STATIC) add_definitions(-D_POSIX_C_SOURCE=200809L) # FIXME: needed for MingW only add_definitions(-D_GNU_SOURCE=1) endif(WIN32) add_executable(checkit_tiff checkit_tiff.c ${checkit_tiff_SOURCES}) add_executable(checkit_check_config checkit_check_config.c ${checkit_tiff_SOURCES}) add_executable(checkit_tiff_risk checkit_tiff_risk.c ${checkit_tiff_risk_SOURCES}) set(CMAKE_EXTRA_INCLUDE_FILES tiff.h) #libpcre #find_package(LIBPCRE REQUIRED) FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h) FIND_LIBRARY(PCRE_LIBRARY NAMES pcre) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR) if (PCRE_FOUND) SET(PCRE_LIBRARIES ${PCRE_LIBRARY}) SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIR}) else(PCRE_FOUND) MESSAGE(FATAL_ERROR "No PCRE library found, add $PCRE_INCLUDE_DIR manually") endif(PCRE_FOUND) #find mmap CHECK_FUNCTION_EXISTS(mmap _HAVE_MMAP) CHECK_FUNCTION_EXISTS(munmap _HAVE_MUNMAP) IF(_HAVE_MMAP AND _HAVE_MUNMAP) MESSAGE(INFO "mmap found") SET(_HAVE__MMAP 1) ENDIF() TARGET_LINK_LIBRARIES(checkit_tiff ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(checkit_check_config ${PCRE_LIBRARIES}) TARGET_LINK_LIBRARIES(checkit_tiff_risk) install( TARGETS checkit_tiff RUNTIME DESTINATION bin LIBRARY DESTINATION lib ) install(DIRECTORY ../example_configs ../tiffs_should_fail ../tiffs_should_pass DESTINATION share/checkit_tiff/ ) file( GLOB README_FILES "../README*" "../FAQ" "../LICENSE" "../TODO" "../BUGS") install(FILES ${README_FILES} DESTINATION share/checkit_tiff/) checkit_tiff-0.4.2/src/Makefile000066400000000000000000000035711327425157300164050ustar00rootroot00000000000000# rule based checks if given TIFF is a specific baseline TIFF # author: Andreas Romeyke, 2015 # licensed under conditions of libtiff # (see http://libtiff.maptools.org/misc.html) ### needs libtiff (>= v4) ### libpcre (>=v3) LIB+=-lpcre -ltiff -lm SANITIZE?=-fsanitize=undefined -fsanitize=shift \ -fsanitize=integer-divide-by-zero -fsanitize=unreachable \ -fsanitize=vla-bound -fsanitize=null -fsanitize=return \ -fsanitize=signed-integer-overflow #-fsanitize=leak CFLAGS?= -g -Wall $(SANITIZE) GRAMMAR=parser/config_dsl.grammar.c SRCS=$(wildcard tagrules/*.c) $(wildcard ifdrules/*.c) $(wildcard helper/*.c) $(wildcard parser/*parser.c) OBJS=$(patsubst %.c,%.o, $(SRCS)) CFLAGS+=-I headers/ # default target all: checkit_tiff checkit_check_config # remove debugging symbols (smaller size) strip: all strip --strip-all checkit_tiff parser/config_parser.c: parser/config_dsl.grammar.c parser/config_dsl.grammar.c: parser/config_dsl.grammar.peg %.o: %.c $(CC) $(CFLAGS) $(INC) -c $< -o $@ # produce parser via PEG %.c: %.peg peg $< > $@ -include version.mk checkit_tiff.o: checkit_tiff.c $(CC) -DVERSION="\"$(BUILD_BRANCH)\"" -DREPO_REVISION="\"0.$(REPO_REVISION)\"" $(CFLAGS) $(INC) -c $< -o $@ # default executable checkit_tiff: $(OBJS) checkit_tiff.o $(CC) -o $@ $(CFLAGS) $(INC) $^ $(LIB) checkit_check_config: $(OBJS) checkit_check_config.o $(CC) -o $@ $(CFLAGS) $(INC) $^ $(LIB) checkit_check_config.c: $(GRAMMAR) # doc doc: ../common/doxygen.conf @doxygen ../common/doxygen.conf # clean workdir clean: @rm -f *.o $(OBJS) @rm -f checkit_tiff checkit_check_config # mrproper clean distclean: clean @find ./ -name "*~" -exec rm -f \{\} \; @rm -f core @rm -Rf doc/ @rm -f .depend @rm -f *.d @rm -f .depend #depend: .depend #.depend: $(SRCS) # rm -f ./.depend # echo $^ # $(CC) $(CFLAGS) -MM $^>>./.depend; #-include .depend .PHONY: all clean distclean strip depend checkit_tiff-0.4.2/src/checkit_check_config.c000066400000000000000000000015071327425157300212020ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "config_parser.h" /* *********** main ************* */ int main() { /* printf("((( print empty plan )))\n"); print_plan(); */ printf("((( parse config file )))\n"); parse_plan (); /* printf("((( print execution plan )))\n"); print_plan(); */ printf("((( execute execution plan )))\n"); // execute_plan(tif); printf("((( clean execution plan )))\n"); clean_plan(); /* printf("((( print empty plan)))\n"); print_plan(); */ printf("((( print internal execution plan )))\n"); exe_printstack_human_readable(); return 0; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/checkit_tiff.c000066400000000000000000000170251327425157300175320ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see file LICENSE) * */ #include "config_parser.h" #include "check.h" #include "check_helper.h" #include "check_renderer.h" #include #include #include #include #include #include #include #ifdef __unix__ #include #include #include #else /* #include */ #include #endif #define FLAGGED 1 #define UNFLAGGED 0 /** help function */ void help () { printf ("checkit_tiff\n"); printf ("\tversion: %s\n", VERSION); printf ("\trevision: %s\n", REPO_REVISION); printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n\n"); printf ("call it with:\n"); printf ("\tcheckit_tiff [-c|-h|-m|-d|-q] []\n"); printf ("\nwhere is the tiff file (or directory) to be validated\n"); printf ("and is the file name of the validation profile\n"); printf ("\t-h this help\n"); printf ("\t-c colorized output using ANSI escape sequences\n"); printf ("\t-m uses memmapped I/O (faster validation, but needs more RAM)\n"); printf ("\t-d check all files in that directory\n"); printf ("\t-q suppresses the output of all valid tags\n"); printf ("example:\n\tcheckit_tiff example_configs/baseline_minimal.cfg tiffs_should_pass/minimal_valid.tiff \n"); printf ("\n"); } int check_specific_tiff_file( const char * tiff_file, int use_memmapped) { GET_EMPTY_RET(res) /* init render pipeline */ retmsg_t * render_pipeline = malloc( sizeof( retmsg_t) ); if (NULL == render_pipeline) { exit (could_not_allocate_memory); } retmsg_t * actual_render = render_pipeline; actual_render->rm_type = rm_file; actual_render->rm_msg = malloc ( sizeof(char) * VALUESTRLEN ); if (NULL == actual_render->rm_msg) { exit (could_not_allocate_memory); } actual_render->next=NULL; assert(NULL != tiff_file); strncpy(actual_render->rm_msg, tiff_file, VALUESTRLEN); /* parse TIFF file */ ctiff_t * ctif = initialize_ctif( tiff_file, use_memmapped?is_memmap:is_filep ); res = parse_header_and_endianess( ctif ); if (res.returncode != is_valid) { assert(NULL != res.value_found); __add_to_render_pipeline_via_strncpy(&actual_render, res.value_found, rm_hard_error); __add_to_render_pipeline_via_strncpy(&actual_render, "", rm_endtiff); //printf("res.val='%s'\n", res.value_found); goto renderer_exit; } uint32 offset; res=get_first_IFD(ctif, &offset); if (res.returncode != is_valid) { assert(NULL != res.value_found); __add_to_render_pipeline_via_strncpy(&actual_render, res.value_found, rm_hard_error); __add_to_render_pipeline_via_strncpy(&actual_render, "", rm_endtiff); goto renderer_exit; } execute_plan(ctif); res = print_plan_results( actual_render); renderer_exit: { const char * render_result_string = renderer( render_pipeline ); printf("%s\n", render_result_string); /* free all entries of render pipeline */ __clean_render_pipeline( render_pipeline ); free((void *) render_result_string); } free_ctif( ctif ); if (NULL != res.value_found) { free(res.value_found); res.value_found = NULL; } return res.returncode; } /** main */ int main (int argc, char * argv[]) { printf("'%s' version: %s\n", argv[0], VERSION); printf ("\trevision: %s\n", REPO_REVISION); printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n"); int c; int flag_check_directory=UNFLAGGED; int flag_use_memorymapped_io=UNFLAGGED; while ((c = getopt (argc, argv, "chmdx:q")) != -1) { switch (c) { case 'h': /* help */ help(); exit (0); case 'c': /* colorize output */ set_renderer_to_ansi(); break; case 'x': /* xml output */ set_renderer_to_xml( optarg); break; case 'd': /* check directory */ flag_check_directory = FLAGGED; printf("\nCheck all files in given directory\n"); break; case 'm': /* use memory mapped I/O */ flag_use_memorymapped_io=FLAGGED; break; case 'q': /* suppresses output of valid rules/tags */ set_renderer_to_quiet(); break; case '?': /* something goes wrong */ /* if (optopt == 'r') { fprintf (stderr, "Option -%c requires an argument.\n", optopt); return (-1); } else*/ if (isprint (optopt)) { fprintf (stderr, "Unknown option `-%c'.\n", optopt); return (-1); } else if (0 !=optopt) { fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return (-1); } break; default: abort(); } } if (argc - optind < 2) { help(); fprintf( stderr, "%s needs at least two arguments, first should be the config-file, second the TIFF-file\nexample:\n\t %s example_configs/baseline_minimal.cfg tiffs_should_pass/minimal_valid.tiff\n", argv[0], argv[0]); exit (EXIT_FAILURE); } const char *cfg_file=argv[optind]; printf("cfg_file=%s\n", cfg_file); int is_valid = 0; int index_of_tiff_file_or_dir = optind+1; do { const char *tiff_file_or_dir=argv[index_of_tiff_file_or_dir++]; printf("tiff file/dir=%s\n", tiff_file_or_dir); if (flag_check_directory == FLAGGED) { /* iterate through all files */ size_t len = strlen( tiff_file_or_dir); char tiff_dir [ len+1 ]; strncpy(tiff_dir, tiff_file_or_dir, len); tiff_dir[ len ] = 0; DIR *dir; /* remove trailing / */ char *dirsuffix = strrchr(tiff_dir, '/'); if (dirsuffix != NULL) { /* found a / */ if ( 0 == strcmp( dirsuffix, "/" ) ) { /* ok, ends with / */ /* remove last / */ assert(len >= 1); // or whatever you want to do with short strings tiff_dir[len-1] = 0; } } /* iterate through all files in given dir */ if ((dir = opendir (tiff_file_or_dir)) != NULL) { /* print all the files and directories within directory */ struct dirent *ent; while ((ent = readdir (dir)) != NULL) { struct stat attribute; len = strlen( tiff_dir ) + strlen( ent->d_name ) + 2; char fqname [ len ]; snprintf( fqname, len, "%s/%s", tiff_dir, ent->d_name); if (stat( fqname, &attribute) == -1) { fprintf (stderr, "could not stat on file '%s' in directory '%s' (%s)\n", ent->d_name, tiff_dir, fqname); exit(EXIT_FAILURE); } if(attribute.st_mode & S_IFREG) { printf ("%s\n", fqname); parse_plan_via_file(cfg_file); is_valid += check_specific_tiff_file( fqname, flag_use_memorymapped_io); clean_plan(); printf("\n"); } } closedir (dir); } else { /* could not open directory */ fprintf( stderr, "directory '%s' could not be opened\n", tiff_file_or_dir); exit(EXIT_FAILURE); } } else { /* use tiff_file_or_dir */ parse_plan_via_file(cfg_file); is_valid = check_specific_tiff_file( tiff_file_or_dir, flag_use_memorymapped_io); clean_plan(); } } while (index_of_tiff_file_or_dir < argc ); if (0 == is_valid) { exit(EXIT_SUCCESS); } else { exit(EXIT_FAILURE); } } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/checkit_tiff_risk.c000066400000000000000000000051771327425157300205670ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015/16 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #ifdef __unix__ #include #include #include #else /* #include */ #include #endif #include #define FLAGGED 1 #define UNFLAGGED 0 /** help function */ void help () { printf ("checkit_tiff_risk\n"); printf("licensed under conditions of libtiff (see http://libtiff.maptools.org/misc.html)\n\n"); printf ("call it with:\n"); printf ("\tcheckit_tiff_risk [-m|-h|-s] \n"); printf ("\nwhere is the tiff file\n"); printf ("\t-h this help\n"); printf ("\t-m prints a memory map\n"); printf ("\t-s prints statistics\n"); printf ("example:\n\tcheckit_tiff -m tiffs_should_pass/minimal_valid.tiff\n"); printf ("\n"); } /* *********** main ************* */ int main(int argc, char * argv[]) { int c; int flag_print_map = UNFLAGGED; int flag_print_stats = UNFLAGGED; while ((c = getopt (argc, argv, "hms")) != -1) { switch (c) { case 'h': /* help */ help(); exit (0); case 'm': /* mem map */ flag_print_map = FLAGGED; break; case 's': /* stats */ flag_print_stats = FLAGGED; break; case '?': /* something goes wrong */ /* if (optopt == 'r') { fprintf (stderr, "Option -%c requires an argument.\n", optopt); return (-1); } else*/ if (isprint (optopt)) { fprintf (stderr, "Unknown option `-%c'.\n", optopt); return (-1); } else if (0 !=optopt) { fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); return (-1); } break; default: abort(); } } if (argc - optind != 1) { help(); fprintf( stderr, "%s needs at least one arguments, example:\n\t %s tiffs_should_pass/minimal_valid.tiff\n", argv[0], argv[0]); exit (EXIT_FAILURE); } const char *tiff_file=argv[optind]; ctiff_t * ctif = initialize_ctif( tiff_file, is_filep ); parse_header_and_endianess( ctif ); uint32 offset; ret_t res=get_first_IFD(ctif, &offset); mem_map_t * memmap_p = scan_mem_map(ctif); if (FLAGGED == flag_print_map) print_mem_map ( memmap_p ); if (FLAGGED == flag_print_stats) print_mem_stats( memmap_p ); return 0; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/headers/000077500000000000000000000000001327425157300163525ustar00rootroot00000000000000checkit_tiff-0.4.2/src/headers/check.h000066400000000000000000000275501327425157300176110ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see file LICENSE) * */ #ifndef _FIXIT_TIFF_CHECK #define _FIXIT_TIFF_CHECK #include #include "tiff.h" #include #include #include #include typedef int thandle_t; typedef uint16 tag_t; typedef enum{ true=1, false=0 } bool_t; typedef enum{ is_memmap, is_filep } ct_ioflag_t ; /* flag */ typedef enum{ has_sorted_tags, has_unsorted_tags, unknown_tag_order } tagorder_t; typedef struct ctiff_s { ct_ioflag_t ioflag; tagorder_t tagorder; int tag_cache[65536]; uint8 * streamp; /* TODO: address of memory-mapped tif stream */ uint8 * actual_streamp; uint32 streamlen; /* TODO: length of tif stream/file (in bytes) */ thandle_t fd; /* filedescriptor */ uint32 ifd0pos; /* offset in tif stream (in bytes) */ uint16 ifd0c; /* count of tags in first ifd */ char isbyteswapped; /* true if BigEndian */ char *filename; /* filename */ /* TODO: add file size */ } ctiff_t; typedef enum{ rm_default, rm_file, rm_rule, rm_tag, rm_value, rm_expected, rm_hard_error, rm_error, rm_warning, rm_precondition, rm_logicalor_error, rm_logicalor_valid, rm_is_valid, rm_endrule, rm_endtiff, rm_mode, rm_lineno, rm_error_description, rm_summary_valid, rm_summary_invalid, } rm_type_t; typedef struct retmsg_s { rm_type_t rm_type; char * rm_msg; struct retmsg_s * next; } retmsg_t; #define ICC_ERROR_OFFSET 100 typedef enum { is_valid=0, /* no problems detected */ calling_error_count_size, /* a called function has wrong arguments */ could_not_allocate_memory, /* malloc fails */ could_not_print, /* snprintf, fprintf, print fails */ should_not_occur, /* dummy, for dead code */ tagerror_expected_count_differs, /* if a tag reports count=m, but the rule expects count=n */ tagerror_expected_count_iszero, /* if a tag reports count=0, but the rule expects count=n */ tagerror_expected_count_isgreaterone, tagerror_value_differs, /* if a tag reports value=m, but the rule expects value=n */ tagerror_unexpected_type_found, /* if a tag reports a type=m, but a type=n was expected */ tagerror_datetime_not_plausible, /* if a datetime tag has date values out of range */ tagerror_datetime_wrong_format, /* if a datetime tag has date with wrong format string */ tagerror_datetime_wrong_size, /* if a datetime tag has date with wrong size */ tagerror_value_not_found, /* if a value of a given tag is not found */ tagwarn_type_of_unknown_tag_could_not_be_checked, /* there is no explicite type check defined yet */ tag_exist, /* if a tag exists, but should not (only used by fc_notag) */ tag_does_not_exist, /* if a tag does not exist, but should (only used by fc_tag_quiet) */ tagerror_encoded_as_value_excited_space, /* tag encoded as value instead as offset, but there is no enough space to hold it, pE. ICC-Profile encoded without offset */ tagerror_pcre_nomatch, /* regex does not match value */ pcre_compile_error, /* regex is wrong */ tagerror_multiple_zeros_in_asciivalue, /* doubled \0 in string */ tagerror_no_zero_as_end_of_string_in_asciivalue, tagerror_denominator_is_zero_in_fract, ifderror_offset_used_twice, ifderror_multiple_ifd_detected, ifderror_tags_not_in_ascending_order, tagerror_offset_not_word_aligned, ifderror_offset_not_word_aligned, iccerror_profileclass= ICC_ERROR_OFFSET + 0, /* profile class ('%s'), should be one of following strings for device classes: 'scnr', 'mntr', 'prtr' or for profile classes: 'link', 'spac', 'abst', 'nmcl'" */ iccerror_colorspacedata= ICC_ERROR_OFFSET + 1, /* colorspace data ('%s'), should be one of following strings: 'XYZ ' 'Lab ' 'Luv ' 'YCbr' 'Yvx ' 'RGB ' 'GRAY' 'HSV ' 'HLS ' 'CMYK' 'CMY ' '2CLR' '3CLR' '4CLR' '5CLR' '6CLR' '7CLR' '8CLR' '9CLR' 'ACLR' 'BCLR' 'CCLR' 'DCLR' 'ECLR' 'FCLR'" */ iccerror_connectionspacedata= ICC_ERROR_OFFSET + 2, /* "connection space data ('%s') should be one of following strings: 'XYZ ' 'Lab '" */ iccerror_primaryplatformsignature= ICC_ERROR_OFFSET + 3, /* primary plattform signature ('%s') should be empty or one of following strings: 'APPL', 'MSFT', 'SGI ', 'SUNW', 'TGNT' */ iccerror_header_1v43_2010= ICC_ERROR_OFFSET + 4, /* Invalid ICC profile 1v43_2010, see http://www.color.org/specification/ICC1v43_2010-12.pdf for details */ iccerror_header_v240_v430= ICC_ERROR_OFFSET + 5, /* Invalid ICC profile ICC.1:2001-04, see http://www.color.org/ICC_Minor_Revision_for_Web.pdf for details */ iccerror_header_generic= ICC_ERROR_OFFSET + 6, /* size < 10 */ iccerror_preferredcmmtype= ICC_ERROR_OFFSET + 7, /* preferred cmmtype ('%s') should be empty or (possibly, because ICC validation is alpha code) one of following strings: 'ADBE' 'ACMS' 'appl' 'CCMS' 'UCCM' 'UCMS' 'EFI ' 'FF ' 'EXAC' 'HCMM' 'argl' 'LgoS' 'HDM ' 'lcms' 'KCMS' 'MCML' 'WCS ' 'SIGN' 'RGMS' 'SICC' 'TCMM' '32BT' 'WTG ' 'zc00'" */ iccerror_committed_size_differs = ICC_ERROR_OFFSET + 8, iccerror_header_v500_2016 = ICC_ERROR_OFFSET +9, iccerror_header_version_undefined = ICC_ERROR_OFFSET +10, iccerror_header_version_outdated = ICC_ERROR_OFFSET +11, tiff_seek_error_header, tiff_read_error_header, tiff_seek_error_offset, tiff_read_error_offset, tiff_byteorder_error, /* not an expected byteorder found */ tiff_ifd0_offset_must_be_greater_than_eight, /* must be greater than 8, because first 8 Bytes contains the TIFF header */ code_error_streampointer_empty, code_error_filedescriptor_empty, code_error_ctif_empty, parser_error_wrong_function_found_in_parser_state_exe_stack, parser_logicalor_error, tagerror_expected_offsetdata, tagerror_count_results_in_offsets_overflow, /* example: rational is defined as 2 uint32. offset is defined as uint32. If we read count>2147483647 we got offset overflow */ parser_logical_combine_open, /* if fc_logicalcombine was called first (no error) */ parser_logical_combine_close, /* if fc_logicalcombine was called first (no error) */ tagerror_offset_is_zero, } returncode_t; typedef struct ret_s { returncode_t returncode; char * value_found; int logical_or_count; } ret_t; typedef struct ifd_entry_s { uint32 count; /* count of data */ TIFFDataType datatype; enum{ is_offset, is_value, is_error } value_or_offset; union { uint32 data32; uint16 data16[2]; uint8 data8[4]; uint32 data32offset; }; } ifd_entry_t; typedef struct offset_s { uint32 count; /* count of data */ TIFFDataType datatype; union { uint8 *data8p; uint16 *data16p; uint32 *data32p; char *datacharp; int8 *datas8p; int16 *datas16p; int32 *datas32p; float *datafloatp; double *datadoublep; uint64 *data64p; int64 *datas64p; }; } offset_t; typedef enum { mt_unused, /* memory areas, which are not referenced within TIFF file */ mt_constant, /* constant values, which are fix part of TIFF file */ mt_ifd, /* memory areas, which are parts of the IFD (but no value!) */ mt_offset_to_ifd0, mt_offset_to_ifd, /* offset to nex ifd */ mt_ifd_embedded_standardized_value, /* memory areas, with standardized values embedded in ifd */ mt_ifd_embedded_registered_value, /* memory areas, with registered values embedded in ifd */ mt_ifd_embedded_private_value, /* memory areas, with private values embedded in ifd */ mt_ifd_offset_to_standardized_value, /* memory areas, which points to standardized values */ mt_ifd_offset_to_registered_value, /* memory areas, which points to registered values */ mt_ifd_offset_to_private_value, /* memory areas, which points to private values */ mt_ifd_offset_to_stripoffsets, /* offsets which points to stripoffsets */ mt_stripoffset_value, /* offsets which points to stripoffset values, hint: if compression is used stripbytecounts holds only decompressed values! */ mt_standardized_value, /* memory areas, which contains standardized values */ mt_registered_value, /* memory areas, which contains registered values */ mt_private_value, /* memory areas, which contains private values */ mt_END_marker } memtype_t; static const char* memtype_string[] = { "unused/unknown", /* memory areas", which are not referenced within TIFF file */ "constant", /* constant values", which are fix part of TIFF file */ "ifd", /* memory areas", which are parts of the IFD (but no value!) */ "offset_to_ifd0", /* offset to nex ifd */ "offset_to_ifd", /* offset to nex ifd */ "ifd_embedded_standardized_value", /* memory areas", with standardized values embedded in ifd */ "ifd_embedded_registered_value", /* memory areas", with registered values embedded in ifd */ "ifd_embedded_private_value", /* memory areas", with private values embedded in ifd */ "ifd_offset_to_standardized_value", /* memory areas", which points to standardized values */ "ifd_offset_to_registered_value", /* memory areas", which points to registered values */ "ifd_offset_to_private_value", /* memory areas", which points to private values */ "ifd_offset_to_stripoffsets", /* offsets which points to stripoffsets */ "stripoffset_value", /* stripoffset values, hint: if compression is used stripbytecounts holds only decompressed values! */ "standardized_value", /* memory areas", which contains standardized values */ "registered_value", /* memory areas", which contains registered values */ "private_value", /* memory areas", which contains private values */ }; typedef struct mem_map_entry_s { uint32 offset; /* address within the tiff */ uint32 count; /* count of bytes beginning with offset */ memtype_t mem_type; /* type of memory */ } mem_map_entry_t; typedef struct mem_map_s { int count; mem_map_entry_t * base_p; uint32 max_len; /* TIFF length */ int max_entries; } mem_map_t; #define MAXSTRLEN 1024 #define EXPECTSTRLEN 500 #define VALUESTRLEN 500 #define TIFFAILSTRLEN (EXPECTSTRLEN + VALUESTRLEN) #define MAXRESULT 200000 returncode_t tifp_check( ctiff_t * ctif); /* ret_t tif_returns(tag_t tag, const char* expected, const char* value); ret_t tif_fails_tag(tag_t tag, const char* expected, const char* value); ret_t tif_fails(const char* fail_message); ret_t tif_fails_by_returns( ret_t ret ); ret_t tif_rules_tag(tag_t tag, const char *msg); ret_t tif_rules(const char *msg); ret_t tif_files(const char *msg); ret_t tif_no_tag(tag_t tag); ret_t _empty_result(); */ const char * float2str(float v); const char* tag2str(tag_t tag); const char* int2str(int v); const char* frac2str(int d, int n); const char* range2str(int d, int n); off_t ct_seek(ctiff_t * ctif, off_t pos, int whence); ssize_t ct_read(ctiff_t * ctif, void *buf, size_t count); ret_t check_tag_has_some_of_these_values( ctiff_t * ctif, tag_t tag, int count, const unsigned int * values); ret_t check_tag_has_valuelist( ctiff_t * ctif, tag_t tag, int count, const unsigned int * values); ret_t check_tag_has_value_in_range(ctiff_t * ctif, tag_t tag, unsigned int a, unsigned int b); ret_t check_tag_has_value(ctiff_t * ctif, tag_t tag, unsigned int value); ret_t check_tag_has_value_quiet(ctiff_t * ctif, tag_t tag, unsigned int expected_value); ret_t check_tag(ctiff_t * ctif, tag_t tag); ret_t check_tag_quiet(ctiff_t * ctif, tag_t tag); ret_t check_notag(ctiff_t * ctif, tag_t tag); ret_t check_tag_has_valid_type(ctiff_t * ctif, tag_t tag); ret_t check_datetime(ctiff_t * ctif); ret_t check_icc(ctiff_t * ctif); ret_t check_has_only_one_ifd(ctiff_t * ctif); ret_t check_tagorder(ctiff_t * ctif); ret_t check_tag_has_valid_asciivalue(ctiff_t * ctif, tag_t tag); ret_t check_tag_has_value_matching_regex(ctiff_t * ctif, tag_t tag, const char* regex_string); ret_t check_all_offsets_are_word_aligned(ctiff_t * ctif); ret_t check_all_offsets_are_used_once_only(ctiff_t * ctif); ret_t check_all_offsets_are_greater_zero(ctiff_t * ctif); ret_t check_all_IFDs_are_word_aligned(ctiff_t * ctif); mem_map_t * scan_mem_map(ctiff_t * ctif) ; void print_mem_map( mem_map_t * memmap_p); void print_mem_stats( mem_map_t * memmap_p); #endif /* _FIXIT_TIFF_CHECK */ checkit_tiff-0.4.2/src/headers/check_helper.h000066400000000000000000000047111327425157300211420ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #ifndef _FIXIT_TIFF_CHECK_HELPER #define _FIXIT_TIFF_CHECK_HELPER #include #include "msg_tiffparse.h" //#include //#include #define TIFF_ANY 0 void TIFFSwabShort(uint16 *a); void TIFFSwabLong(uint32 *a); /* helper */ long long fsize(int fd); ret_t check_tag_has_fvalue(ctiff_t * ctif, tag_t tag, float value); ret_t check_tag_has_u16value(ctiff_t * ctif, tag_t tag, uint16 value); ret_t check_tag_has_u32value(ctiff_t * ctif, tag_t tag, uint32 value); uint32 TIFFGetRawTagTypeListEntry( ctiff_t * ctif, int tagidx ); tag_t TIFFGetRawTagListEntry( ctiff_t * ctif, int tagidx ) ; int TIFFGetRawTagListCount (ctiff_t * ctif, uint32 ifdpos) ; TIFFDataType TIFFGetRawTagType(ctiff_t * ctif, tag_t tag); ifd_entry_t TIFFGetRawIFDEntry( ctiff_t * ctif, tag_t tag); ifd_entry_t TIFFGetRawTagIFDListEntry( ctiff_t * ctif, int tagidx ); int TIFFGetRawTagListIndex(ctiff_t * ctif, tag_t tag); ret_t TIFFGetFieldASCII(ctiff_t * ctif, const tag_t tag, char** result_string_p, uint32 * result_countp); ret_t TIFFGetFieldLONG(ctiff_t * ctif, const tag_t tag, uint32 ** result_long_p, uint32 * result_countp); ret_t TIFFGetFieldSHORT(ctiff_t * ctif, const tag_t tag, uint16 ** result_short_p, uint32 * result_countp); ret_t TIFFGetFieldRATIONAL(ctiff_t * ctif, const tag_t tag, float ** result_float_p, uint32 * result_countp); ret_t read_offsetdata(ctiff_t * ctif, const uint32 address, const uint32 count, const uint16 datatype, offset_t * result_offsetp, ret_t * ret_p); char * secstrcat (char * dest, const char * src, size_t * maxsize_p); ctiff_t * initialize_ctif( const char * tiff_file, ct_ioflag_t ); void free_ctif( ctiff_t * ctif); uint32 get_ifd0_pos( ctiff_t * ctif); ret_t parse_header_and_endianess(ctiff_t * ctif ); uint32 get_next_ifd_pos( ctiff_t * ctif, uint32 actual_pos ); uint16 get_ifd0_count( ctiff_t * ctif ); char is_byteswapped( ctiff_t * ctif ); ret_t get_first_IFD(ctiff_t * ctif, uint32 * ifd); ret_t set_value_found_ret (ret_t * rp, const char * msg); returncode_t __add_to_render_pipeline_via_strncpy (retmsg_t ** pointer, const char * src, rm_type_t src_type); void __clean_render_pipeline( retmsg_t * pointer ); #define GET_EMPTY_RET(ret) \ ret_t ret; \ ret.value_found = NULL; \ ret.logical_or_count = 0; \ ret.returncode = should_not_occur; #endif checkit_tiff-0.4.2/src/headers/check_renderer.h000066400000000000000000000020131327425157300214620ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #ifndef _FIXIT_TIFF_CHECK_RENDERER #define _FIXIT_TIFF_CHECK_RENDERER #include "check_helper.h" /* 65536 Tags a 256 chars message + 100 Messages */ /* #define RENDERSIZE (65536*256 + 100*256) */ #define RENDERSIZE (4096) typedef enum{ render_default, render_ansi, render_xml} render_type; typedef enum{ within_valid, within_error, within_file, within_summaryerror, within_harderror } render_context_t; const char * renderer ( const retmsg_t * ret ); void set_renderer_to_ansi(); void set_renderer_to_xml(const char *); void set_renderer_to_quiet(); const char * renderer_ansi ( const retmsg_t * ret, short int ); const char * renderer_default ( const retmsg_t * ret, short int ); const char * renderer_xml ( const retmsg_t * ret, const char * xml ); #endif /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/headers/config_parser.h000066400000000000000000000066461327425157300213600ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #ifndef _FIXIT_TIFF_CONFIG_PARSER #define _FIXIT_TIFF_CONFIG_PARSER #include "check.h" typedef enum { mandatory, ifdepends, optdepends, optional } requirements_t; typedef enum { range, logical_or, any, only, regex, ntupel, sbit, iccprofile, datetime, printable_ascii } values_t; typedef enum { no_ref, any_ref, only_ref, range_ref, ntupel_ref, regex_ref } reference_t; typedef enum { mode_baseline=1, mode_enable_type_checks=2, mode_enable_offset_checks=4, mode_enable_ifd_checks=8, } modes_t; /* MINTAGS - MAXTAGS is range of possible existing TAG numbers */ #define MINTAGS 254 #define MAXTAGS 65536 #define MAXINCLUDEDEPTH 1 /* the stack size depends on count of rules and count of numbers, in general * 65536 should be enough. Otherwise you need to increase it */ #define MAXSTACKDEPTH 65536 typedef enum { fc_true, fc_false, fc_tag_has_some_of_these_values, fc_tag_has_valuelist, fc_tag_has_value_in_range, fc_tag_has_value, fc_tag_has_value_quiet, fc_tag, fc_tag_quiet, fc_notag, fc_tag_has_valid_type, fc_datetime, fc_icc, fc_has_only_one_ifd, fc_tagorder, fc_tag_has_valid_asciivalue, fc_tag_has_value_matching_regex, fc_all_offsets_are_word_aligned, fc_all_offsets_are_used_once_only, fc_all_IFDs_are_word_aligned, fc_internal_logic_combine_open, fc_internal_logic_combine_close, fc_all_offsets_are_not_zero, fc_dummy } function_t; #define INTERNALSTACKDEPTH 10 typedef struct internal_entry_s { int lineno; bool_t is_precondition; tag_t tag; function_t function; values_t val_stack[INTERNALSTACKDEPTH]; const char * regex_stack[INTERNALSTACKDEPTH]; unsigned int i_stack[INTERNALSTACKDEPTH]; int i_stackp; int val_stackp; int regex_stackp; } internal_entry_t; typedef struct full_res_s { int lineno; tag_t tag; function_t function; char * expected_value; char * found_value; returncode_t returncode; } full_res_t; typedef struct parser_state_s { // TODO: Anzahl le-Werte für Tupel in Stack speichern int lineno; int valuelist; tag_t tag; tag_t tagref; values_t val_stack[MAXSTACKDEPTH]; const char * regex_stack[MAXSTACKDEPTH]; requirements_t req; unsigned int i_stack[MAXSTACKDEPTH]; int i_stackp; int val_stackp; int regex_stackp; int called_tags[MAXTAGS]; FILE * stream; reference_t any_reference; const char * regex_string; int includedepth; full_res_t result_stack[MAXRESULT]; int result_stackp; int exe_stackp; internal_entry_t exe_stack[MAXSTACKDEPTH]; int mode; bool_t within_logical_or; int logical_elements; } parser_state_t; void _helper_push_result(full_res_t res); full_res_t _helper_pop_result(); void _helper_mark_top_n_results(int n, returncode_t type); full_res_t _helper_get_nth(int n); ret_t call_exec_function(ctiff_t * ctif, ret_t * retp, internal_entry_t * exep); void set_parse_error(char * msg, char * yytext); void execute_plan (ctiff_t * ctif); void print_plan (); ret_t print_plan_results (retmsg_t *); void clean_plan (); void parse_plan (); void parse_plan_via_stream (FILE * file); void parse_plan_via_file (const char * cfg_file); void add_default_rules_to_plan(); void set_include( const char * ); void exe_printstack_human_readable (); void result_push(full_res_t); #endif /* _FIXIT_TIFF_CONFIG_PARSER */ checkit_tiff-0.4.2/src/headers/msg_parser.h000066400000000000000000000010361327425157300206650ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #ifndef _FIXIT_TIFF_MSG_PARSER #define _FIXIT_TIFF_MSG_PARSER #include "config_parser.h" const char * get_parser_function_description (function_t f); const char * get_parser_error_description( returncode_t r); const char * get_parser_function_name( function_t f ); #endif /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/headers/msg_tiffparse.h000066400000000000000000000006771327425157300213660ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #ifndef _FIXIT_TIFF_MSG_TIFFPARSE #define _FIXIT_TIFF_MSG_TIFFPARSE #include "check.h" const char * TIFFTypeName( uint16 tagtype ); const char * TIFFTagName( tag_t tag ); #endif /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/headers/tiff.h000066400000000000000000001057101327425157300174570ustar00rootroot00000000000000/* $Id: tiff.h,v 1.68 2012-08-19 16:56:35 bfriesen Exp $ */ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ #ifndef _TIFF_ #define _TIFF_ #include "tiffconf.h" /* * Tag Image File Format (TIFF) * * Based on Rev 6.0 from: * Developer's Desk * Aldus Corporation * 411 First Ave. South * Suite 200 * Seattle, WA 98104 * 206-622-5500 * * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) * * For BigTIFF design notes see the following links * http://www.remotesensing.org/libtiff/bigtiffdesign.html * http://www.awaresystems.be/imaging/tiff/bigtiff.html */ #define TIFF_VERSION_CLASSIC 42 #define TIFF_VERSION_BIG 43 #define TIFF_BIGENDIAN 0x4d4d #define TIFF_LITTLEENDIAN 0x4949 #define MDI_LITTLEENDIAN 0x5045 #define MDI_BIGENDIAN 0x4550 /* * Intrinsic data types required by the file format: * * 8-bit quantities int8/uint8 * 16-bit quantities int16/uint16 * 32-bit quantities int32/uint32 * 64-bit quantities int64/uint64 * strings unsigned char* */ typedef TIFF_INT8_T int8; typedef TIFF_UINT8_T uint8; typedef TIFF_INT16_T int16; typedef TIFF_UINT16_T uint16; typedef TIFF_INT32_T int32; typedef TIFF_UINT32_T uint32; typedef TIFF_INT64_T int64; typedef TIFF_UINT64_T uint64; /* * Some types as promoted in a variable argument list * We use uint16_vap rather then directly using int, because this way * we document the type we actually want to pass through, conceptually, * rather then confusing the issue by merely stating the type it gets * promoted to */ typedef int uint16_vap; /* * TIFF header. */ typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ } TIFFHeaderCommon; typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ uint32 tiff_diroff; /* byte offset to first directory */ } TIFFHeaderClassic; typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ uint16 tiff_offsetsize; /* size of offsets, should be 8 */ uint16 tiff_unused; /* unused word, should be 0 */ uint64 tiff_diroff; /* byte offset to first directory */ } TIFFHeaderBig; /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, * - items marked with a ! are introduced in revision 6.0. * - items marked with a % are introduced post revision 6.0. * - items marked with a $ are obsoleted by revision 6.0. * - items marked with a & are introduced by Adobe DNG specification. */ /* * Tag data type information. * * Note: RATIONALs are the ratio of two 32-bit integer values. */ typedef enum { TIFF_NOTYPE = 0, /* placeholder */ TIFF_BYTE = 1, /* 8-bit unsigned integer */ TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ TIFF_SHORT = 3, /* 16-bit unsigned integer */ TIFF_LONG = 4, /* 32-bit unsigned integer */ TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ TIFF_SBYTE = 6, /* !8-bit signed integer */ TIFF_UNDEFINED = 7, /* !8-bit untyped data */ TIFF_SSHORT = 8, /* !16-bit signed integer */ TIFF_SLONG = 9, /* !32-bit signed integer */ TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ } TIFFDataType; /* * TIFF Tag Definitions. */ #define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ #define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ #define FILETYPE_PAGE 0x2 /* one page of many */ #define FILETYPE_MASK 0x4 /* transparency mask */ #define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ #define OFILETYPE_IMAGE 1 /* full resolution image data */ #define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ #define OFILETYPE_PAGE 3 /* one page of many */ #define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ #define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ #define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ #define TIFFTAG_COMPRESSION 259 /* data compression technique */ #define COMPRESSION_NONE 1 /* dump mode */ #define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ #define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ #define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ #define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ #define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ #define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ #define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ #define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ #define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ #define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ #define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ #define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ #define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ #define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ #define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ #define COMPRESSION_JBIG 34661 /* ISO JBIG */ #define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ #define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ #define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ #define COMPRESSION_LZMA 34925 /* LZMA2 */ #define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ #define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ #define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ #define PHOTOMETRIC_RGB 2 /* RGB color model */ #define PHOTOMETRIC_PALETTE 3 /* color map indexed */ #define PHOTOMETRIC_MASK 4 /* $holdout mask */ #define PHOTOMETRIC_SEPARATED 5 /* !color separations */ #define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ #define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ #define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ #define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ #define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ #define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ #define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ #define THRESHHOLD_BILEVEL 1 /* b&w art scan */ #define THRESHHOLD_HALFTONE 2 /* or dithered scan */ #define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ #define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ #define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ #define TIFFTAG_FILLORDER 266 /* data order within a byte */ #define FILLORDER_MSB2LSB 1 /* most significant -> least */ #define FILLORDER_LSB2MSB 2 /* least significant -> most */ #define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ #define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ #define TIFFTAG_MAKE 271 /* scanner manufacturer name */ #define TIFFTAG_MODEL 272 /* scanner model name/number */ #define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ #define TIFFTAG_ORIENTATION 274 /* +image orientation */ #define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ #define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ #define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ #define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ #define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ #define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ #define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ #define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ #define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ #define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ #define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ #define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ #define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ #define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ #define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ #define TIFFTAG_PLANARCONFIG 284 /* storage organization */ #define PLANARCONFIG_CONTIG 1 /* single image plane */ #define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ #define TIFFTAG_PAGENAME 285 /* page name image is from */ #define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ #define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ #define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ #define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ #define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ #define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ #define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ #define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ #define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ #define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ #define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ #define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ #define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ #define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ #define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ #define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ #define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ #define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ #define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ #define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ #define RESUNIT_NONE 1 /* no meaningful units */ #define RESUNIT_INCH 2 /* english */ #define RESUNIT_CENTIMETER 3 /* metric */ #define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ #define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ #define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ #define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ #define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ #define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ #define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ #define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ #define TIFFTAG_SOFTWARE 305 /* name & release */ #define TIFFTAG_DATETIME 306 /* creation date and time */ #define TIFFTAG_ARTIST 315 /* creator of image */ #define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ #define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ #define PREDICTOR_NONE 1 /* no prediction scheme used */ #define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ #define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ #define TIFFTAG_WHITEPOINT 318 /* image white point */ #define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ #define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ #define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ #define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ #define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ #define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ #define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ #define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ #define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ #define CLEANFAXDATA_CLEAN 0 /* no errors detected */ #define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ #define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ #define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ #define TIFFTAG_SUBIFD 330 /* subimage descriptors */ #define TIFFTAG_INKSET 332 /* !inks in separated image */ #define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ #define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ #define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ #define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ #define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ #define TIFFTAG_TARGETPRINTER 337 /* !separation target */ #define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ #define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ #define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ #define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ #define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ #define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ #define SAMPLEFORMAT_INT 2 /* !signed integer data */ #define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ #define SAMPLEFORMAT_VOID 4 /* !untyped data */ #define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ #define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ #define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ #define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ #define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */ #define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */ #define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */ #define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */ #define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ #define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ /* Tags 400-435 are from the TIFF/FX spec */ #define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ #define TIFFTAG_PROFILETYPE 401 /* ! */ #define PROFILETYPE_UNSPECIFIED 0 /* ! */ #define PROFILETYPE_G3_FAX 1 /* ! */ #define TIFFTAG_FAXPROFILE 402 /* ! */ #define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ #define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ #define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ #define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ #define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ #define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ #define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ #define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ #define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ #define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ #define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ #define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ #define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ #define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ #define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ #define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ #define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ #define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ /* * Tags 512-521 are obsoleted by Technical Note #2 which specifies a * revised JPEG-in-TIFF scheme. */ #define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ #define JPEGPROC_BASELINE 1 /* !baseline sequential */ #define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ #define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ #define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ #define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ #define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ #define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ #define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ #define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ #define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ #define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ #define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ #define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ #define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ #define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ #define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ #define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ #define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */ #define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */ /* tags 32952-32956 are private tags registered to Island Graphics */ #define TIFFTAG_REFPTS 32953 /* image reference points */ #define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ #define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ #define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ /* tags 32995-32999 are private tags registered to SGI */ #define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ #define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ #define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ #define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ /* tags 33300-33309 are private tags registered to Pixar */ /* * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH * are set when an image has been cropped out of a larger image. * They reflect the size of the original uncropped image. * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used * to determine the position of the smaller image in the larger one. */ #define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ #define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ /* Tags 33302-33306 are used to identify special image modes and data * used by Pixar's texture formats. */ #define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ #define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ #define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ #define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 /* tag 33405 is a private tag registered to Eastman Kodak */ #define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ #define TIFFTAG_COPYRIGHT 33432 /* copyright string */ /* IPTC TAG from RichTIFF specifications */ #define TIFFTAG_RICHTIFFIPTC 33723 /* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ #define TIFFTAG_STONITS 37439 /* Sample value to Nits */ /* tag 34929 is a private tag registered to FedEx */ #define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ #define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ /* Adobe Digital Negative (DNG) format tags */ #define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ #define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ #define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ #define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name */ #define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */ #define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ #define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ #define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */ #define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ #define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */ #define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */ #define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */ #define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ #define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */ #define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */ #define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */ #define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */ #define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ #define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ #define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */ #define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */ #define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/ #define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */ #define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */ #define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */ #define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ #define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */ #define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of the green pixels in the blue/green rows track the values of the green pixels in the red/green rows */ #define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ #define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ #define TIFFTAG_LENSINFO 50736 /* info about the lens */ #define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ #define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */ #define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ #define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ #define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */ #define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ #define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ #define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ #define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */ #define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file */ #define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */ #define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */ #define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */ #define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ #define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */ #define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ #define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ /* tag 65535 is an undefined tag used by Eastman Kodak */ #define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ /* * The following are ``pseudo tags'' that can be used to control * codec-specific functionality. These tags are not written to file. * Note that these values start at 0xffff+1 so that they'll never * collide with Aldus-assigned tags. * * If you want your private pseudo tags ``registered'' (i.e. added to * this file), please post a bug report via the tracking system at * http://www.remotesensing.org/libtiff/bugs.html with the appropriate * C definitions to add. */ #define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ #define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ #define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ #define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ #define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ #define FAXMODE_WORDALIGN 0x0008 /* word align row */ #define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ #define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ /* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ #define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ #define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ #define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ #define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ #define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ #define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ /* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ #define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ #define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ #define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ #define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ #define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ #define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ #define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ #define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ /* 65550-65556 are allocated to Oceana Matrix */ #define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ #define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ #define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ #define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ #define DCSIMAGERFILTER_IR 0 /* infrared filter */ #define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ #define DCSIMAGERFILTER_CFA 2 /* color filter array */ #define DCSIMAGERFILTER_OTHER 3 /* other filter */ #define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ #define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ #define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ #define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ #define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ #define TIFFTAG_DCSGAMMA 65554 /* gamma value */ #define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ #define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ /* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ #define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ #define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ /* 65559 is allocated to Oceana Matrix */ #define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ #define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ #define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ #define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ #define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ #define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ #define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ #define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ #define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ #define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ #define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ #define PERSAMPLE_MERGED 0 /* present as a single value */ #define PERSAMPLE_MULTI 1 /* present as multiple values */ /* * EXIF tags */ #define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ #define EXIFTAG_FNUMBER 33437 /* F number */ #define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ #define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ #define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ #define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ #define EXIFTAG_EXIFVERSION 36864 /* Exif version */ #define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ #define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */ #define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ #define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ #define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ #define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ #define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ #define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ #define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ #define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ #define EXIFTAG_METERINGMODE 37383 /* Metering mode */ #define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ #define EXIFTAG_FLASH 37385 /* Flash */ #define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ #define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ #define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ #define EXIFTAG_USERCOMMENT 37510 /* User comments */ #define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ #define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ #define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ #define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ #define EXIFTAG_COLORSPACE 40961 /* Color space information */ #define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ #define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ #define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ #define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ #define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ #define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ #define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ #define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ #define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ #define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ #define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ #define EXIFTAG_FILESOURCE 41728 /* File source */ #define EXIFTAG_SCENETYPE 41729 /* Scene type */ #define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ #define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ #define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ #define EXIFTAG_WHITEBALANCE 41987 /* White balance */ #define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ #define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ #define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_CONTRAST 41992 /* Contrast */ #define EXIFTAG_SATURATION 41993 /* Saturation */ #define EXIFTAG_SHARPNESS 41994 /* Sharpness */ #define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ #define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ #endif /* _TIFF_ */ /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: * mode: c * c-basic-offset: 8 * fill-column: 78 * End: */ checkit_tiff-0.4.2/src/headers/tiffconf.h000066400000000000000000000065451327425157300203330ustar00rootroot00000000000000/* libtiff/tiffconf.h. Generated from tiffconf.h.in by configure. */ /* Configuration defines for installed libtiff. This file maintained for backward compatibility. Do not use definitions from this file in your programs. */ #ifndef _TIFFCONF_ #define _TIFFCONF_ /* Signed 16-bit type */ #define TIFF_INT16_T signed short /* Signed 32-bit type */ #define TIFF_INT32_T signed int /* Signed 64-bit type */ #define TIFF_INT64_T signed long /* Signed 8-bit type */ #define TIFF_INT8_T signed char /* Unsigned 16-bit type */ #define TIFF_UINT16_T unsigned short /* Unsigned 32-bit type */ #define TIFF_UINT32_T unsigned int /* Unsigned 64-bit type */ #define TIFF_UINT64_T unsigned long /* Unsigned 8-bit type */ #define TIFF_UINT8_T unsigned char /* Signed size type */ #define TIFF_SSIZE_T signed long /* Pointer difference type */ #define TIFF_PTRDIFF_T ptrdiff_t /* Define to 1 if the system has the type `int16'. */ /* #undef HAVE_INT16 */ /* Define to 1 if the system has the type `int32'. */ /* #undef HAVE_INT32 */ /* Define to 1 if the system has the type `int8'. */ /* #undef HAVE_INT8 */ /* Compatibility stuff. */ /* Define as 0 or 1 according to the floating point format suported by the machine */ #define HAVE_IEEEFP 1 /* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ #define HOST_FILLORDER FILLORDER_LSB2MSB /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ #define HOST_BIGENDIAN 0 /* Support CCITT Group 3 & 4 algorithms */ #define CCITT_SUPPORT 1 /* Support JPEG compression (requires IJG JPEG library) */ #define JPEG_SUPPORT 1 /* Support JBIG compression (requires JBIG-KIT library) */ #define JBIG_SUPPORT 1 /* Support LogLuv high dynamic range encoding */ #define LOGLUV_SUPPORT 1 /* Support LZW algorithm */ #define LZW_SUPPORT 1 /* Support NeXT 2-bit RLE algorithm */ #define NEXT_SUPPORT 1 /* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation fails with unpatched IJG JPEG library) */ #define OJPEG_SUPPORT 1 /* Support Macintosh PackBits algorithm */ #define PACKBITS_SUPPORT 1 /* Support Pixar log-format algorithm (requires Zlib) */ #define PIXARLOG_SUPPORT 1 /* Support ThunderScan 4-bit RLE algorithm */ #define THUNDER_SUPPORT 1 /* Support Deflate compression */ #define ZIP_SUPPORT 1 /* Support strip chopping (whether or not to convert single-strip uncompressed images to mutiple strips of ~8Kb to reduce memory usage) */ #define STRIPCHOP_DEFAULT TIFF_STRIPCHOP /* Enable SubIFD tag (330) support */ #define SUBIFD_SUPPORT 1 /* Treat extra sample as alpha (default enabled). The RGBA interface will treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many packages produce RGBA files but don't mark the alpha properly. */ #define DEFAULT_EXTRASAMPLE_AS_ALPHA 1 /* Pick up YCbCr subsampling info from the JPEG data stream to support files lacking the tag (default enabled). */ #define CHECK_JPEG_YCBCR_SUBSAMPLING 1 /* Support MS MDI magic number files as TIFF */ #define MDI_SUPPORT 1 /* * Feature support definitions. * XXX: These macros are obsoleted. Don't use them in your apps! * Macros stays here for backward compatibility and should be always defined. */ #define COLORIMETRY_SUPPORT #define YCBCR_SUPPORT #define CMYK_SUPPORT #define ICC_SUPPORT #define PHOTOSHOP_SUPPORT #define IPTC_SUPPORT #endif /* _TIFFCONF_ */ checkit_tiff-0.4.2/src/helper/000077500000000000000000000000001327425157300162165ustar00rootroot00000000000000checkit_tiff-0.4.2/src/helper/check_helper.c000066400000000000000000000051461327425157300210040ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include #include "check.h" #include "check_helper.h" #include "check_renderer.h" #include #include #include #include #include /* #define DEBUG */ char * secstrcat (char * dest, const char * src, size_t * maxsize_p) { assert(NULL != maxsize_p); size_t maxsize = *maxsize_p; if (NULL == dest) { fprintf(stderr, "internal error, dest is NULL!\n"); exit(EXIT_FAILURE); } if (NULL == src) { } else { int destsize = strnlen(dest, maxsize); int srclen = strnlen(src, maxsize); if (destsize+srclen < maxsize-1) { strncat( dest, src, srclen); } else { int new_maxsize=(((destsize+srclen) / RENDERSIZE)+1) * RENDERSIZE-1; if (new_maxsize < 4096*RENDERSIZE && new_maxsize > 0) { char * dest_new = NULL; dest_new = realloc(dest, (new_maxsize+1) * sizeof(char)); if (NULL == dest_new) { perror( "Could not realloc memory"); exit( could_not_allocate_memory ); } else { *maxsize_p = new_maxsize; dest = dest_new; strncat( dest, src, destsize +srclen); } } } } return dest; } const char * float2str(float v) { char array[VALUESTRLEN]; snprintf(array, sizeof(array), "%f", v); return strdup(array); } const char* int2str(int v) { char array[VALUESTRLEN]; snprintf(array, sizeof(array), "%i", v); return strdup(array); } const char* frac2str(int d, int n) { char array[VALUESTRLEN]; snprintf(array, sizeof(array), "%i/%i", d, n); return strdup(array); } void TIFFSwabShort(uint16 *a) { uint16 b = ((*a & 0xff) << 8) | ((*a >> 8) & 0xff); *a=b; } void TIFFSwabLong(uint32 *a) { uint8 b0 = (*a) & 0xff; uint8 b1 = (*a >> 8) & 0xff; uint8 b2 = (*a >> 16) & 0xff; uint8 b3 = (*a >> 24) & 0xff; uint32 b = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; *a=b; } long long fsize(int fd) { struct stat st; fstat(fd, &st); return st.st_size; } ret_t set_value_found_ret (ret_t * rp, const char * msg) { assert( NULL != rp); assert( NULL != msg); rp->value_found=malloc(sizeof(char) * VALUESTRLEN); if (NULL == rp->value_found) { rp->returncode=could_not_allocate_memory; } else { memset(rp->value_found, '\0', VALUESTRLEN); // printf("DEBUG='%s'\n", msg); strncpy(rp->value_found, msg, VALUESTRLEN-1); // printf("DEBUG2='%s'\n", rp->value_found); } return *rp; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/check_print.c000066400000000000000000000170221327425157300206550ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see file LICENSE) * */ #define DEBUG #define _GNU_SOURCE #include #include #include "check.h" #include "check_helper.h" #ifdef WIN32 static inline char *strndup(const char *s, size_t n) { char *result; size_t len = strlen (s); if (n < len) len = n; result = (char *) malloc (len + 1); if (!result) return 0; result[len] = '\0'; return (char *) strncpy (result, s, len); } #endif returncode_t __add_to_render_pipeline_via_strncpy (retmsg_t ** pointer, const char * src, rm_type_t src_type) { assert(pointer != NULL); retmsg_t * actual_render = NULL; actual_render = *pointer; assert(actual_render != NULL); assert(src != NULL); assert(actual_render->next==NULL); assert(actual_render->rm_msg != NULL); actual_render->next = malloc ( sizeof(retmsg_t)); if (NULL == actual_render->next) { exit( could_not_allocate_memory); // return could_not_allocate_memory; } /* actual_render->next->rm_msg = malloc ( sizeof(char) * VALUESTRLEN ); if (NULL == actual_render->next->rm_msg) { exit (could_not_allocate_memory); // return could_not_allocate_memory; } memset( actual_render->next->rm_msg, '\0', VALUESTRLEN); */ actual_render->next->rm_msg = calloc (VALUESTRLEN, sizeof(char) ); if (NULL == actual_render->next->rm_msg) { exit (could_not_allocate_memory); // return could_not_allocate_memory; } strncpy(actual_render->next->rm_msg, src, VALUESTRLEN-1 ); actual_render->next->rm_type = src_type; // fprintf(stderr, "rendertype=%i rendermsg='%s'\n",actual_render->next->rm_type, actual_render->next->rm_msg ); actual_render->next->next=NULL; actual_render = actual_render->next; assert(actual_render != NULL); assert(actual_render->rm_msg != NULL); *pointer = actual_render; return is_valid; } void __clean_render_pipeline( retmsg_t * pointer ) { assert(pointer != NULL); retmsg_t * next = pointer->next; if (NULL != pointer->rm_msg) { free( pointer->rm_msg); pointer->rm_msg = NULL; } if (NULL != next) __clean_render_pipeline( next ); free( pointer ); pointer = NULL; } /* ret_t tif_fails(const char* fail_message) { ret_t res; char * str =malloc( sizeof(char) *MAXSTRLEN ); if (NULL==str) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (str, MAXSTRLEN-1, "%s", fail_message); res.returnmsg = NULL; res.returncode=1; res.returnmsg = malloc( sizeof( retmsg_t ) ); if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; res.returnmsg->rm_type=rm_hard_error; res.count = 1; res.returnmsg->rm_msg = str; return res; } ret_t tif_fails_tag(tag_t tag, const char* expected, const char* value) { ret_t res = tif_returns( tag, expected, value); return res; } ret_t tif_rules_tag(tag_t tag, const char *msg) { ret_t res; res.returnmsg = NULL; res.returncode=0; res.count = 3; res.returnmsg = malloc( sizeof( retmsg_t ) * res.count ); if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_rules_tag\n"); exit(EXIT_FAILURE); }; retmsg_t * p = res.returnmsg; // header p->rm_type=rm_rule; p->rm_msg = "check if "; // tag p++; p->rm_type=rm_tag; p->rm_msg = malloc( sizeof(char) *MAXSTRLEN ); if (NULL==p->rm_msg) { fprintf(stderr, "could not allocate memory for 3tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (p->rm_msg, MAXSTRLEN-1, "tag %s ", tag2str(tag)); // rule p++; p->rm_type=rm_rule; p->rm_msg = strndup( msg, MAXSTRLEN); return res; } ret_t tif_no_tag(tag_t tag) { ret_t res; res.returnmsg = NULL; res.returncode=1; res.count = 4; res.returnmsg = malloc( sizeof( retmsg_t ) * res.count ); if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_rules_tag\n"); exit(EXIT_FAILURE); }; retmsg_t * p = res.returnmsg; // header p->rm_type=rm_error; p->rm_msg = ""; // tag p++; p->rm_type=rm_tag; p->rm_msg = malloc( sizeof(char) *MAXSTRLEN ); if (NULL==p->rm_msg) { fprintf(stderr, "could not allocate memory for 3tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (p->rm_msg, MAXSTRLEN-1, "tag %s ", tag2str(tag)); // expected p++; p->rm_type=rm_expected; p->rm_msg = "is found"; // value p++; p->rm_type=rm_value; p->rm_msg = ", but is not whitelisted (or rule has no matched dependency)"; return res; } ret_t tif_rules(const char *msg) { ret_t res; res.returnmsg = NULL; res.returncode=0; res.count = 2; res.returnmsg = malloc( sizeof( retmsg_t ) * res.count ); if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_rules_tag\n"); exit(EXIT_FAILURE); }; retmsg_t * p = res.returnmsg; // header p->rm_type=rm_default; p->rm_msg = "check if "; // rule p++; p->rm_type=rm_rule; p->rm_msg = strndup( msg, MAXSTRLEN); return res; } ret_t tif_files(const char *msg) { ret_t res; res.returnmsg = NULL; res.returncode=0; res.count = 2; res.returnmsg = malloc( sizeof( retmsg_t ) * res.count ); if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_rules_tag\n"); exit(EXIT_FAILURE); }; retmsg_t * p = res.returnmsg; // header p->rm_type=rm_default; p->rm_msg = "tiff file="; // rule p++; p->rm_type=rm_file; p->rm_msg = strndup( msg, MAXSTRLEN); // printf( "%s", renderer( res) ); return res; } ret_t tif_returns(tag_t tag, const char* expected, const char* value) { ret_t res; res.returnmsg = NULL; res.returncode=1; res.count = 4; res.returnmsg = malloc( sizeof( retmsg_t) * res.count ); retmsg_t * p = res.returnmsg; if (NULL==res.returnmsg) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; // header p->rm_type=rm_error; p->rm_msg = ""; // tag p++; p->rm_type=rm_tag; p->rm_msg = malloc( sizeof(char) *MAXSTRLEN ); if (NULL==p->rm_msg) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (p->rm_msg, MAXSTRLEN-1, "tag %s", tag2str( tag)); // expected p++; p->rm_type=rm_expected; p->rm_msg = malloc( sizeof(char) *MAXSTRLEN ); if (NULL==p->rm_msg) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (p->rm_msg, MAXSTRLEN-1, " should have value %s", expected); // value p++; p->rm_type=rm_value; p->rm_msg = malloc( sizeof(char) *MAXSTRLEN ); if (NULL==p->rm_msg) { fprintf(stderr, "could not allocate memory for tif_fails\n"); exit(EXIT_FAILURE); }; snprintf (p->rm_msg, MAXSTRLEN-1, ", but has value (values or count) %s", value); return res; } ret_t tif_fails_by_returns( ret_t ret ) { return ret; } ret_t _empty_result() { ret_t t; t.returncode=is_valid; t.returnmsg=NULL; t.returnmsg = malloc( sizeof( retmsg_t) * t.count ); retmsg_t * p = t.returnmsg; if (NULL==t.returnmsg) { fprintf(stderr, "could not allocate memory for _empty_result\n"); exit(EXIT_FAILURE); }; return t; } */ returncode_t tifp_check( ctiff_t * ctif) { if (NULL == ctif) { return code_error_ctif_empty; }; if (0 > ctif->fd) { return code_error_filedescriptor_empty; }; if (NULL == ctif->streamp) { return code_error_streampointer_empty; }; return should_not_occur; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/check_renderer.c000066400000000000000000000021341327425157300213250ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include #include "check.h" #include "check_helper.h" #include "check_renderer.h" #include #include #include #include render_type render_engine=render_default; short int is_quiet = 1; const char * xmlfile = NULL; void set_renderer_to_quiet() { is_quiet=0; } void set_renderer_to_ansi() { if (isatty (STDOUT_FILENO)) { render_engine=render_ansi; } } void set_renderer_to_xml( const char * given_xmlfile) { render_engine=render_xml; xmlfile = given_xmlfile; } const char * renderer ( const retmsg_t * ret ) { // call debug renderer switch (render_engine) { case render_xml: return renderer_xml( ret, xmlfile); case render_ansi: return renderer_ansi( ret, is_quiet ); default: return renderer_default( ret, is_quiet ); } return ""; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/check_tiffparse.c000066400000000000000000001074011327425157300215050ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see file LICENSE) * */ #define _GNU_SOURCE #include #include "check.h" #include "check_helper.h" #include "msg_tiffparse.h" #include #include #include #include #include #ifdef _HAVE__MMAP #include #endif #include /* #define DEBUG */ off_t ct_seek(ctiff_t * ctif, off_t pos, int whence) { #ifdef _HAVE__MMAP switch (ctif->ioflag) { case is_filep: assert(ctif->fd >= 0); // TODO: add checks if seek will be outside of file!!! return lseek(ctif->fd, pos, whence); break; case is_memmap: assert( ctif->streamp != NULL); assert( ctif->actual_streamp != NULL); switch (whence) { case SEEK_SET: ctif->actual_streamp = ctif->streamp + pos; break; case SEEK_CUR: ctif->actual_streamp+=pos; break; case SEEK_END: ctif->actual_streamp = ctif->streamp + ctif->streamlen + pos; break; } int testpos = ctif->actual_streamp - ctif->streamp; if ( testpos > ctif->streamlen) { /* * fprintf(stderr, "seek offset outside of file on new pos=%i (filesize=%i)\n", testpos, ctif->streamlen); * exit(EXIT_FAILURE); */ return -1; } if ( testpos < 0 ) { /* * fprintf(stderr, "seek offset outside of file on new pos=%i (filesize=%i)\n", testpos, ctif->streamlen); * exit(EXIT_FAILURE); */ return -1; } return ctif->actual_streamp - ctif->streamp; break; } #else assert(ctif->fd >= 0); // TODO: add checks if seek will be outside of file!!! return lseek(ctif->fd, pos, whence); #endif } ssize_t ct_read(ctiff_t * ctif, void *buf, size_t count) { #ifdef _HAVE__MMAP switch (ctif->ioflag) { case is_filep: // TODO: add checks if seek will be outside of file!!! assert(ctif->fd >= 0); return read(ctif->fd, buf, count); break; case is_memmap: { assert( ctif->streamp != NULL); assert( ctif->actual_streamp != NULL); int testpos = (ctif->actual_streamp+count) - (ctif->streamp); if ( testpos > ctif->streamlen) { /* * fprintf(stderr, "read offset outside of file on new pos=%i (filesize=%i)\n", testpos, ctif->streamlen); * exit(EXIT_FAILURE); */ return -1; } if ( testpos < 0 ) { /* * fprintf(stderr, "read offset outside of file on new pos=%i (filesize=%i)\n", testpos, ctif->streamlen); * exit(EXIT_FAILURE); */ return -1; } memcpy(buf, ctif->actual_streamp, count); ctif->actual_streamp+=count; return count; /* break; */ } } #else // TODO: add checks if seek will be outside of file!!! assert(ctif->fd >= 0); return read(ctif->fd, buf, count); #endif } int TIFFGetRawTagListIndex(ctiff_t * ctif, tag_t tag) { /* find n-th entry in IFD for given tag, return -1 if not found */ /* for (int i= 0; i < get_ifd0_count( ctif ); i++) { if (tag > 253 && tag == TIFFGetRawTagListEntry( ctif, i )) { return i; }; } */ switch (ctif->tagorder) { case unknown_tag_order: { ctif->tagorder=has_sorted_tags; int count = get_ifd0_count( ctif); if (0 == count) { return -1; } tag_t last = TIFFGetRawTagListEntry(ctif, 0); for (int i= 1; i < get_ifd0_count( ctif ); i++) { tag_t current = TIFFGetRawTagListEntry( ctif, i ); if (last >= current) { ctif->tagorder=has_unsorted_tags; break; } last = current; }; /* if (has_sorted_tags == ctif->tagorder) { */ for (int i= 0; i < get_ifd0_count( ctif ); i++) { tag_t tag = TIFFGetRawTagListEntry( ctif, i ); ctif->tag_cache[tag] = i; } return ctif->tag_cache[tag]; /* } */ } break; case has_unsorted_tags: case has_sorted_tags: return ctif->tag_cache[tag]; } return -1; } //------------------------------------------------------------------------------ ret_t check_tag_has_fvalue(ctiff_t * ctif, tag_t tag, float value) { GET_EMPTY_RET(ret) tifp_check( ctif); float * valp = NULL; uint32 found; ret =TIFFGetFieldRATIONAL(ctif, tag, &valp, &found); if (1 == found) { float val = * valp; if ( fabs(val - value) < 0.01 ) { ret.returncode=is_valid; return ret; } else { ret = set_value_found_ret(&ret, float2str(val)) ; ret.returncode = tagerror_value_differs; } } return ret; } //------------------------------------------------------------------------------ ret_t check_tag_has_u16value(ctiff_t * ctif, tag_t tag, uint16 value) { GET_EMPTY_RET(ret) tifp_check( ctif); uint16 * valp = NULL; uint32 found; ret=TIFFGetFieldSHORT(ctif, tag, &valp, &found); if (1 == found) { uint16 val = *valp; if ( val == value ) { ret.returncode=is_valid; return ret; } else { ret = set_value_found_ret(&ret, int2str(val)); ret.returncode = tagerror_value_differs; return ret; } } return ret; } //------------------------------------------------------------------------------ ret_t check_tag_has_u32value(ctiff_t * ctif, tag_t tag, uint32 value) { GET_EMPTY_RET(ret) tifp_check( ctif); uint32 * valp = NULL; uint32 found; ret=TIFFGetFieldLONG(ctif, tag, &valp, &found); if (1 == found) { uint32 val = *valp; if ( val == value ) { ret.returncode=is_valid; return ret; } else { ret = set_value_found_ret(&ret, int2str(val)); ret.returncode = tagerror_value_differs; return ret; } } return ret; } ret_t parse_header_and_endianess(ctiff_t * ctif) { GET_EMPTY_RET(ret) /* seek the image file directory (bytes 4-7) */ //ct_seek(fd, (off_t) 0, SEEK_SET); if ( ct_seek(ctif, 0, SEEK_SET) != 0) { ret = set_value_found_ret(&ret, "TIFF header ct_seek error to 0"); ret.returncode=tiff_seek_error_header; return ret; } uint16 header; uint16 magic; int endianness; if ( ct_read( ctif, &header, 2) != 2 ) { ret = set_value_found_ret(&ret, "TIFF Header ct_read error to magic byte header (first 2 bytes)"); ret.returncode=tiff_read_error_header; return ret; } if (header == 0x4949) endianness = 0; /* little endian */ else if (header == 0x4d4d) endianness = 1; /* big endian */ else { char errmsg[VALUESTRLEN]=""; snprintf (errmsg, VALUESTRLEN, "TIFF Header error, not Byte Order Bytes for TIFF: 0x%04x", header); if (header == 0x4550) { strcat(errmsg, ", could be a Microsoft Document Image file (little endian), if header begins with by 0x45 0x50 0x2a 0x00"); } ret=set_value_found_ret(&ret, errmsg); ret.returncode = tiff_byteorder_error; return ret; } ctif->isbyteswapped = endianness; if ( ct_read( ctif, &magic, 2) != 2 ) { ret = set_value_found_ret(&ret, "TIFF Header ct_read error to magic byte header (second 2 bytes == 42)"); ret.returncode=tiff_read_error_header; return ret; } uint16 magic2 = magic; if (endianness) TIFFSwabShort( &magic2 ); /* big endian */ if (magic2 == 42) { ret.returncode=is_valid; return ret; } else { char errmsg[VALUESTRLEN]=""; snprintf (errmsg, VALUESTRLEN, "TIFF Header error, not a MAGIC BYTE for TIFF: 0x%04x\n", magic); if (magic2==0x002b) strcat(errmsg, ", but could be a BigTIFF, see http://www.awaresystems.be/imaging/tiff/bigtiff.html"); if (magic2==0x0055) strcat(errmsg, ", but could be a Panasonic Raw/RW2, see http://libopenraw.freedesktop.org/wiki/Panasonic_RAW/"); if (magic2==0x01bc) strcat(errmsg, ", but could be a JPEG XR, see http://www.itu.int/rec/T-REC-T.832"); if (magic2==0x314e) strcat(errmsg, ", but could be a Navy Image FileFormat, see http://www.navsea.navy.mil/nswc/carderock/tecinfsys/cal-std/doc/28002c.pdf"); if (magic2==0x4352) strcat(errmsg, ", but could be a DNG camera profile, see http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf"); if (magic2==0x4f52) strcat(errmsg, ", but could be an Olympus ORF, see http://libopenraw.freedesktop.org/wiki/Olympus_ORF/"); if (magic2==0x5352) strcat(errmsg, ", but could be an Olympus ORF, see http://libopenraw.freedesktop.org/wiki/Olympus_ORF/"); ret = set_value_found_ret(&ret, errmsg); ret.returncode = tiff_byteorder_error; return ret; } ret.returncode = should_not_occur; assert( ret.returncode != should_not_occur); return ret; } ret_t get_first_IFD(ctiff_t * ctif, uint32 * ifd) { GET_EMPTY_RET(ret) int isByteSwapped = ctif->isbyteswapped; /* seek the image file directory (bytes 4-7) */ if (ct_seek(ctif, 4, SEEK_SET) != 4 ) { ret = set_value_found_ret(&ret, "TIFF Header seak error, seek set to byte 4"); ret.returncode=tiff_seek_error_header; return ret; } uint32 offset; if ( ct_read( ctif, &offset, 4) != 4 ) { ret = set_value_found_ret(&ret, "TIFF Header ct_read error, reading 4 bytes from 4"); ret.returncode=tiff_read_error_header; return ret; } if (isByteSwapped) { TIFFSwabLong (&offset); } if (offset <= 7) { char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "pointer to IFD0 is %u", offset); ret=set_value_found_ret(&ret, msg); ret.returncode=tiff_ifd0_offset_must_be_greater_than_eight; return ret; } ctif->ifd0pos=offset; if (ct_seek(ctif, offset, SEEK_SET) != offset ) { char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "TIFF Header seek error, seek set to byte %u", offset); ret=set_value_found_ret(&ret, msg); ret.returncode=tiff_seek_error_header; return ret; } uint16 count; if ( ct_read( ctif, &count, 2) != 2 ) { ret=set_value_found_ret(&ret, "TIFF Header ct_read error2, reading ifd0 count (2 bytes)"); ret.returncode=tiff_read_error_header; return ret; } if (is_byteswapped(ctif)) TIFFSwabShort(&count); ctif->ifd0c = count; *ifd = offset; ret.returncode=is_valid; return ret; } /* scans first IDF and returns the n-th tag */ tag_t TIFFGetRawTagListEntry( ctiff_t * ctif, int tagidx ) { int byteswapped = is_byteswapped(ctif); int count = get_ifd0_count( ctif); assert( count > 0); /* ct_read count of tags (2 Bytes) */ /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * count); ct_seek(ctif, ctif->ifd0pos+2, SEEK_SET); /* IFD0 plus 2byte to get IFD-entries */ if ( ct_read( ctif, ifdentries, 12 * count) != 12*count ) { /* FIXME: replace perror/exit with own error handling routine */ perror ("TIFF Header ct_read error3"); exit( EXIT_FAILURE ); } uint8 * e = ifdentries; uint16 ret = 0; /* for (i = 0; i= 0); e+=(12*tagidx); uint8 lo = *e; e++; uint8 hi = *e; e++; uint16 tagid = ((uint16) hi << 8) + lo; if (byteswapped) TIFFSwabShort(&tagid); //printf("tag idx=%i, tag=%u (0x%04x) (0x%02x) (0x%02x)\n", i, tagid, tagid, hi, lo); ret = tagid; // LABEL1: /* loop each tag until end or given tag found */ free( ifdentries ); return ret; } #define OFFSET_MALLOC(ctif_p, offsetdata, offset_type, count ) {\ if(ctif_p->streamlen < sizeof(offset_type) * count) {\ char msg[VALUESTRLEN]; \ snprintf(msg, VALUESTRLEN, "TIFF Offset ct_read error, try to read from offset count=%lu bytes, but file has size=%u\n", sizeof(offset_type) * count, ctif_p->streamlen); \ *ret_p = set_value_found_ret( ret_p, msg); \ ret_p->returncode = tiff_seek_error_offset;\ return * ret_p;\ }\ offsetdata = NULL; offsetdata = malloc ( sizeof(offset_type) * count);\ if (NULL == offsetdata) {\ fprintf( stderr, "could not allocate memory for offset_t\n");\ exit (EXIT_FAILURE);\ }\ if ( ct_read( ctif_p, offsetdata, sizeof(offset_type) * count) != (sizeof(offset_type) *count) ) {\ /* fprintf(stderr, "TIFF Offset ct_read error, try to read from offset count=%lu bytes\n", sizeof(offset_type) * count); */\ /* exit( EXIT_FAILURE ); */\ char msg[VALUESTRLEN]; \ snprintf(msg, VALUESTRLEN, "TIFF Offset ct_read error, try to read from offset count=%lu bytes\n", sizeof(offset_type) * count); \ *ret_p = set_value_found_ret( ret_p, msg); \ ret_p->returncode = tiff_read_error_offset; \ return *ret_p; \ }\ } void offset_swabshort(ctiff_t * ctif, uint16 * address, uint16 count) { if (is_byteswapped(ctif)) for (int i=0; icount = count; offset_p->datatype = datatype; ret_p->returncode = is_valid; /* ct_read and seek to IFD address */ if (ct_seek(ctif, address, SEEK_SET) != address) { offset_p->count = -1; ret_p->returncode = tiff_seek_error_offset; return * ret_p; } #ifdef DEBUG printf("read_offsetdata(tif, address=%u, count=%u, datatype=%u)\n", address, count, datatype); #endif switch (datatype) { case 1: /* 8-bit unsigned integer */ case 7: /* !8-bit untyped data */ /* offset_p->data8p = NULL; offset_p->data8p = malloc ( sizeof(uint8) * count); if (ct_read(fd, offset_p->data8p, sizeof(uint8) * count) != sizeof(uint8) *count) perror ("TIFF Offset ct_read error"); */ OFFSET_MALLOC(ctif, offset_p->data8p, uint8, count) break; case 2: /* 8-bit bytes w/ last byte null */ assert( sizeof(char) == sizeof(uint8)); OFFSET_MALLOC(ctif, offset_p->datacharp, char, count) break; case 6: /* !8-bit signed integer */ OFFSET_MALLOC(ctif, offset_p->datas8p, int8, count) break; case 3: /* 16-bit unsigned integer */ OFFSET_MALLOC(ctif, offset_p->data16p, uint16, count) offset_swabshort(ctif, offset_p->data16p, count); break; case 8: /* !16-bit signed integer */ OFFSET_MALLOC(ctif, offset_p->datas16p, int16, count) offset_swabshort(ctif, (uint16 *) offset_p->datas16p, count); break; case 4: /* 32-bit unsigned integer */ case 13: /* %32-bit unsigned integer (offset) */ OFFSET_MALLOC(ctif, offset_p->data32p, uint32, count) offset_swablong(ctif, offset_p->data32p, count); break; case 9: /* !32-bit signed integer */ OFFSET_MALLOC(ctif, offset_p->datas32p, uint32, count) offset_swablong(ctif, (uint32 *) offset_p->data32p, count); break; case 5: /* 64-bit unsigned fraction */ OFFSET_MALLOC(ctif, offset_p->data32p, uint32, 2*count) /* because numerator + denominator */ offset_swablong(ctif, offset_p->data32p, 2*count); break; case 10: /* !64-bit signed fraction */ fprintf(stderr, "offsetdata datatype=%i not supported yet", datatype); exit(EXIT_FAILURE); case 11: /* !32-bit IEEE floating point */ assert( sizeof(float) == 4); OFFSET_MALLOC(ctif, offset_p->datafloatp, float, count) break; case 12: /* !64-bit IEEE floating point */ assert( sizeof(double) == 8); OFFSET_MALLOC(ctif, offset_p->datadoublep, double, count) break; case 16: /* BigTIFF 64-bit unsigned integer */ case 18: /* BigTIFF 64-bit unsigned integer (offset) */ assert( sizeof(double) == 8); OFFSET_MALLOC(ctif, offset_p->data64p, uint64, count) break; case 17: /* BigTIFF 64-bit signed integer */ assert( sizeof(double) == 8); OFFSET_MALLOC(ctif, offset_p->datas64p, int64, count) break; default: /* should not occur */ { char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "offsetdata datatype=%i not supported yet", datatype); *ret_p = set_value_found_ret(ret_p, msg); ret_p->returncode = should_not_occur; assert( ret_p->returncode != should_not_occur); return *ret_p; } }; #ifdef DEBUG printf ("is valid offset\n"); printf ("RET=%s\n", get_parser_error_description(ret_p->returncode)); #endif return *ret_p; } /* scans first IDF and returns the type of the n-th tag */ ifd_entry_t TIFFGetRawTagIFDListEntry( ctiff_t * ctif, int tagidx ) { int tagcount = get_ifd0_count( ctif); assert( tagcount > 0); int byteswapped = is_byteswapped(ctif); #ifdef DEBUG printf(" count of tags = %i\n", tagcount); #endif // int fd = TIFFFileno( tif); //printf("count %i\n", count); /* ct_read count of tags (2 Bytes) */ ifd_entry_t ifd_entry; ifd_entry.value_or_offset = is_error; /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * tagcount); ct_seek(ctif, ctif->ifd0pos+2, SEEK_SET); /* IFD0 plus 2byte to get IFD-entries */ if ( ct_read( ctif, ifdentries, 12 * tagcount) != 12*tagcount ) { /* FIXME: replace perror/exit with own error handling routine */ perror ("TIFF Header ct_read error4"); exit( EXIT_FAILURE ); } uint8 * e = ifdentries; for (int i = 0; i 4) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; ifd_entry.data8[0] = data0; ifd_entry.data8[1] = data1; ifd_entry.data8[2] = data2; ifd_entry.data8[3] = data3; #ifdef DEBUG printf("data8[0]=%u\n", data0); printf("data8[1]=%u\n", data1); printf("data8[2]=%u\n", data2); printf("data8[3]=%u\n", data3); #endif }; break; case 3: /* 16-bit unsigned integer */ case 8: /* !16-bit signed integer */ if (count > 2) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; uint16 w0 = (data0) + ((uint16) data1<<8); uint16 w1 = (data2) + ((uint16) data3<<8); if (byteswapped) { TIFFSwabShort( &w0 ); TIFFSwabShort( &w1 ); } ifd_entry.data16[0] = w0; ifd_entry.data16[1] = w1; #ifdef DEBUG printf("data16[0]=%u\n", w0); printf("data16[1]=%u\n", w1); #endif }; break; case 4: /* 32-bit unsigned integer */ case 9: /* !32-bit signed integer */ if (count > 1) { /* offset */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } else { /* values */ ifd_entry.value_or_offset=is_value; ifd_entry.data32=value_or_offset; #ifdef DEBUG printf("data32[0]=%u\n", value_or_offset); #endif }; break; case 5: /* 64-bit unsigned fraction */ case 10: /* !64-bit signed fraction */ case 11: /* !32-bit IEEE floating point */ case 12: /* !64-bit IEEE floating point */ case 13: /* %32-bit unsigned integer (offset) */ case 16: /* BigTIFF 64-bit unsigned integer */ case 17: /* BigTIFF 64-bit signed integer */ case 18: /* BigTIFF 64-bit unsigned integer (offset) */ ifd_entry.value_or_offset=is_offset; ifd_entry.data32offset=value_or_offset; } free( ifdentries ); #ifdef DEBUG printf("tag idx=%i, tag=%u (0x%04x) tagtype=0x%04x is_offset=%s count=%u value_or_offset=0x%08x\n", i, tagid, tagid, tagtype, (ifd_entry.value_or_offset==is_offset ? "true" : "false"), count, value_or_offset); #endif return ifd_entry; } e+=10; } /* loop each tag until end or given tag found */ free( ifdentries ); return ifd_entry; } /* TODO */ ifd_entry_t TIFFGetRawIFDEntry( ctiff_t * ctif, tag_t tag) { int tagidx = -1; for (int i= 0; i < get_ifd0_count( ctif ); i++) { if (tag > 253 && tag == TIFFGetRawTagListEntry( ctif, i )) { tagidx= i; break; }; }; ifd_entry_t ifd_entry; if (tagidx >= 0) { ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); } else { /* tag not defined */ printf("\ttag %u (%s) was not found, but requested because defined\n", tag, TIFFTagName(tag)); ifd_entry.value_or_offset = is_error; ifd_entry.count = 0; } return ifd_entry; } /* scans first IDF and returns the type of the n-th tag */ uint32 TIFFGetRawTagTypeListEntry( ctiff_t * ctif, int tagidx ) { if (tagidx >= 0) { ifd_entry_t ifd_entry; ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); return ifd_entry.datatype; } else { /* tag not defined */ fprintf(stderr, "tagidx should be greater equal 0"); exit(EXIT_FAILURE); } } /* ct_reads the datatype of given tag on specified TIFF, * because FieldType of libtiff does not return the true value (because it maps * its own datastructure), we need to use this function instead * @param tif pointer to TIFF structure * @param tag tag * @return datatype of given tag * if tag does not exists the function aborts with an error */ TIFFDataType TIFFGetRawTagType(ctiff_t * ctif, tag_t tag) { int tagidx = -1; for (int i= 0; i < get_ifd0_count( ctif ); i++) { if (tag > 253 && tag == TIFFGetRawTagListEntry( ctif, i )) { tagidx= i; break; }; }; if (tagidx >= 0) { TIFFDataType datatype = TIFFGetRawTagTypeListEntry( ctif, tagidx ); #ifdef DEBUG printf("### datatype=%i \n", datatype); #endif return datatype; } else { /* tag not defined */ printf("\ttag %u (%s) was not found, but requested because defined\n", tag, TIFFTagName(tag)); return -1; } } ctiff_t * initialize_ctif(const char * tiff_file, ct_ioflag_t ioflag) { ctiff_t * ctif = malloc ( sizeof( ctiff_t) ); if (NULL == ctif) { fprintf( stderr, "could not allocate memory for ctiff_t\n"); exit (EXIT_FAILURE); } /* load tiff file */ #ifdef __WIN32__ int tif = open(tiff_file, O_RDONLY | O_BINARY); #else int tif = open(tiff_file, O_RDONLY); #endif if (-1 == tif) { fprintf( stderr, "file '%s' could not be opened\n", tiff_file); exit (EXIT_FAILURE); }; ctif->fd = tif; ctif->streamlen = fsize(tif); ctif->streamp = NULL; ctif->actual_streamp = NULL; ctif->tagorder=unknown_tag_order; for (int i= 0; i < 65536; i++) { ctif->tag_cache[i]= -1; } #ifdef _HAVE__MMAP switch (ioflag) { case is_filep: { /* streamlen */ break; } case is_memmap: { void * tifmap = mmap( NULL, ctif->streamlen, PROT_READ, MAP_PRIVATE, tif, 0 ); if (MAP_FAILED == tifmap) { fprintf( stderr, "file '%s' could not be mem-mapped, %s\n", tiff_file, strerror(errno)); exit (EXIT_FAILURE); }; ctif->streamp=tifmap; ctif->actual_streamp=tifmap; break; } } #endif ctif->ioflag = ioflag; ctif->filename = strdup(tiff_file); ctif->ifd0pos= 0; ctif->ifd0c= 0; return ctif; } void free_ctif( ctiff_t * ctif) { assert( NULL != ctif); if (NULL != ctif->filename) free(ctif->filename); ctif->filename=NULL; switch (ctif->ioflag) { case is_filep: { break; } case is_memmap: { /* TODO */ break; } } close(ctif->fd); ctif->fd = -1; free (ctif); /* ctif = NULL; */ } uint32 get_ifd0_pos( ctiff_t * ctif ) { assert( NULL != ctif); return ctif->ifd0pos; } uint16 get_ifd0_count( ctiff_t * ctif ) { assert( NULL != ctif); return ctif->ifd0c; } char is_byteswapped( ctiff_t * ctif ) { assert( NULL != ctif); return ctif->isbyteswapped; } uint32 get_next_ifd_pos(ctiff_t * ctif, uint32 actual_pos) { assert( NULL != ctif); ct_seek(ctif, actual_pos, SEEK_SET); uint16 count; if ( ct_read( ctif, &count, 2) != 2 ) { /* FIXME: replace perror/exit with own error handling routine */ perror ("TIFF Header ct_read error2"); exit( EXIT_FAILURE ); } if (ctif->isbyteswapped) TIFFSwabShort(&count); ct_seek(ctif, 12 * count, SEEK_CUR); uint32 offset; if ( ct_read( ctif, &offset, 4) != 4 ) { /* FIXME: replace perror/exit with own error handling routine */ perror ("TIFF Header ct_read error3"); exit( EXIT_FAILURE ); } if (ctif->isbyteswapped) TIFFSwabLong(&offset); return offset; } ret_t TIFFGetFieldASCII(ctiff_t * ctif, const tag_t tag, char** string_pp, uint32 * countp ) { assert( *string_pp == NULL); assert( countp != NULL); GET_EMPTY_RET(ret) int tagidx = TIFFGetRawTagListIndex(ctif, tag); if (tagidx >= 0) { /* there exists the tag */ ifd_entry_t entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); /* assert (entry.datatype == TIFF_ASCII); */ if (entry.datatype != TIFF_ASCII) { char msg[200]; snprintf(msg, 200, "data of type ASCII expected, but got type %s", TIFFTypeName(entry.datatype)); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_unexpected_type_found; return ret; } *countp = entry.count; /* *(string_pp) = malloc( sizeof(char) * entry.count +1); if (NULL == (* string_pp)) { ret.returncode=could_not_allocate_memory; return ret; } memset(*string_pp, '\0', entry.count+1); */ *(string_pp) = calloc(entry.count+1, sizeof(char) ); if (NULL == (* string_pp)) { ret.returncode=could_not_allocate_memory; return ret; } if (entry.value_or_offset == is_value) { assert (entry.count >= 0 && entry.count <= 4); for (uint32 i=0; i= 0) { /* there exists the tag */ ifd_entry_t entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); uint32 overflow = (0xffffffff / (sizeof(uint32))); if (entry.count > overflow) { char msg[200]; snprintf(msg, 200, "count=%u overflow boundary=%u", entry.count, overflow); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_count_results_in_offsets_overflow; return ret; } *countp = entry.count; *(long_pp) = malloc( sizeof(uint32) * entry.count); if (NULL == (*long_pp)) { ret.returncode=could_not_allocate_memory; return ret; } /* assert (entry.datatype == TIFF_LONG); */ if (entry.datatype != TIFF_LONG) { char msg[200]; snprintf(msg, 200, "data of type LONG expected, but got type %s", TIFFTypeName(entry.datatype)); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_unexpected_type_found; return ret; } if (entry.value_or_offset == is_value) { assert (entry.count >= 0 && entry.count <= 1); //printf("LONG (direct)=%lu\n", entry.data32); memcpy((void *) (*long_pp), (void *) &entry.data32, (sizeof(uint32)*entry.count)); ret.returncode=is_valid; return ret; } else if (entry.value_or_offset == is_offset) { uint32 data32offset = entry.data32offset; offset_t offset; ret = read_offsetdata( ctif, data32offset, entry.count, entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { /* FIXME: free(offset.datacharp); */ return ret; } //printf("LONG (offset)=%lu\n", *offset.datacharp); memcpy((void *) (*long_pp), (void *) offset.datacharp, (sizeof(uint32)*offset.count)); free(offset.datacharp); ret.returncode=is_valid; return ret; } } ret.returncode = tag_does_not_exist; return ret; } ret_t TIFFGetFieldSHORT(ctiff_t * ctif, const tag_t tag, uint16 ** short_pp, uint32 * countp) { assert( *short_pp == NULL); assert( countp != NULL); *countp = -1; /* init */ GET_EMPTY_RET(ret) int tagidx = TIFFGetRawTagListIndex(ctif, tag); if (tagidx >= 0) { /* there exists the tag */ ifd_entry_t entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); uint32 overflow = (0xffffffff / (sizeof(uint16))); if (entry.count > overflow) { char msg[200]; snprintf(msg, 200, "count=%u overflow boundary=%u", entry.count, overflow); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_count_results_in_offsets_overflow; return ret; } *countp = entry.count; *(short_pp) = malloc( sizeof(uint16) * entry.count); if (NULL == *(short_pp)) { ret.returncode=could_not_allocate_memory; return ret; } /* assert (entry.datatype == TIFF_SHORT); */ if (entry.datatype != TIFF_SHORT) { char msg[200]; snprintf(msg, 200, "data of type SHORT expected, but got type %s", TIFFTypeName(entry.datatype)); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_unexpected_type_found; return ret; } if (entry.value_or_offset == is_value) { assert (entry.count >= 0 && entry.count <= 2); memcpy((void *) (*short_pp), (void *) &entry.data16, (sizeof(uint16)*entry.count)); //printf("SHORT (direct)=%u %u\n", entry.data32, **short_pp); ret.returncode=is_valid; return ret; } else if (entry.value_or_offset == is_offset) { uint32 data32offset = entry.data32offset; offset_t offset; ret = read_offsetdata( ctif, data32offset, entry.count, entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { /* FIXME: free(offset.datacharp); */ return ret; } //printf("SHORT (offset)=%u\n", *offset.datacharp); memcpy((void *) (*short_pp), (void *)offset.datacharp, (sizeof(uint16)*offset.count)); free( offset.datacharp ); offset.datacharp=NULL; ret.returncode=is_valid; return ret; } } ret.returncode = tag_does_not_exist; return ret; } ret_t TIFFGetFieldRATIONAL(ctiff_t * ctif, const tag_t tag, float ** float_pp, uint32 * countp) { assert( *float_pp == NULL); assert( countp != NULL); *countp = 0; /* init */ GET_EMPTY_RET(ret) int tagidx = TIFFGetRawTagListIndex(ctif, tag); if (tagidx >= 0) { /* there exists the tag */ ifd_entry_t entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); uint32 overflow = (0xffffffff / (2*sizeof(uint32))); if (entry.count > overflow) { char msg[200]; snprintf(msg, 200, "count=%u overflow boundary=%u", entry.count, overflow); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_count_results_in_offsets_overflow; return ret; } //printf("entry.count=%i\n", entry.count); *countp = entry.count; *(float_pp) = malloc( sizeof(float) * (entry.count)); if (NULL == *(float_pp)) { ret.returncode=could_not_allocate_memory; return ret; } /* assert (entry.datatype == TIFF_RATIONAL); */ if (entry.datatype != TIFF_RATIONAL) { char msg[200]; snprintf(msg, 200, "data of type RATIONAL expected, but got type %s", TIFFTypeName(entry.datatype)); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_unexpected_type_found; return ret; } /* rational is defined as 2x32bits */ if (entry.value_or_offset == is_value) { ret.returncode = tagerror_expected_offsetdata; return ret; } else if (entry.value_or_offset == is_offset) { uint32 data32offset = entry.data32offset; offset_t offset; //printf("data32offset=%u count=%i\n", data32offset, entry.count); ret = read_offsetdata( ctif, data32offset, entry.count, entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { /* FIXME: free(offset.datacharp); */ return ret; } /* copy to a float */ uint32 * orig_data32p = offset.data32p; for (uint32 i = 0; i< entry.count; i++, orig_data32p+=2) { uint32 numerator = *(orig_data32p); uint32 denominator = *(orig_data32p+1); //printf("DEBUG: numerator=%u denumeator=%u\n", numerator, denominator); float v; if (denominator == 0) { v=NAN; } else { v = (float) numerator / (float) denominator; } //printf("DEBUG2: *float_pp[%i]=%f (%u / %u)\n", i, v, numerator, denominator); (*(float_pp))[i]=v; } free( offset.data32p ); offset.data32p=NULL; ret.returncode=is_valid; return ret; } } ret.returncode = tag_does_not_exist; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/renderer/000077500000000000000000000000001327425157300200245ustar00rootroot00000000000000checkit_tiff-0.4.2/src/helper/renderer/check_renderer_ansi.c000066400000000000000000000176001327425157300241510ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include "check_renderer.h" #include /* color definitions, using ISO 6429 as listed in 'man (5) dir_colors' 0 to restore default color 1 for brighter colors 4 for underlined text 5 for flashing text 30 for black foreground 31 for red foreground 32 for green foreground 33 for yellow (or brown) foreground 34 for blue foreground 35 for purple foreground 36 for cyan foreground 37 for white (or gray) foreground 40 for black background 41 for red background 42 for green background 43 for yellow (or brown) background 44 for blue background 45 for purple background 46 for cyan background 47 for white (or gray) background */ #define ANSI_NORMAL "\033[0m" #define ANSI_BOLD "\033[1m" #define ANSI_RED "\033[00;31m" #define ANSI_RED_BOLD "\033[01;31m" #define ANSI_GREEN "\033[00;32m" #define ANSI_GREEN_BOLD "\033[01;32m" #define ANSI_RESET "\033[0m" #define ANSI_BLACK "\033[00;30m" #define ANSI_BLACK_BOLD "\033[01;30m" #define ANSI_BROWN "\033[00;33m" #define ANSI_BLUE "\033[00;34m" #define ANSI_BLUE_BOLD "\033[01;34m" #define ANSI_PURPLE "\033[00;35m" #define ANSI_CYAN "\033[00;36m" #define ANSI_GREY "\033[00;37m" #define ANSI_DARK_GREY "\033[01;30m" #define ANSI_YELLOW "\033[01;33m" #define ANSI_WHITE "\033[01;37m" #define ANSI_INVERSE "\033[7m" const char * renderer_ansi ( const retmsg_t * ret, short int is_quiet ) { assert (ret != NULL); /* char * res = malloc( sizeof(char) * RENDERSIZE); if (NULL == res) { exit(could_not_allocate_memory); } memset( res, '\0', RENDERSIZE); */ char * res = calloc(RENDERSIZE, sizeof(char)); if (NULL == res) { exit(could_not_allocate_memory); } size_t rendersize_res = RENDERSIZE-1; /* char * tmp = malloc( sizeof(char) * RENDERSIZE); if (NULL == tmp) { exit(could_not_allocate_memory); } memset( tmp, '\0', RENDERSIZE); */ char * tmp = calloc( RENDERSIZE, sizeof(char)); if (NULL == tmp) { exit(could_not_allocate_memory); } size_t rendersize_tmp = RENDERSIZE-1; const retmsg_t * startp = ret; short int is_valid = 1; while (NULL != startp) { assert(startp->rm_msg != NULL); switch (startp->rm_type) { case rm_rule: tmp=secstrcat(tmp, ANSI_NORMAL , & rendersize_tmp); tmp=secstrcat(tmp, "\t--> ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_tag: tmp=secstrcat(tmp, "\t", & rendersize_tmp ); tmp=secstrcat(tmp, ANSI_BOLD , & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_mode: tmp=secstrcat(tmp, "\t", & rendersize_tmp ); tmp=secstrcat(tmp, ANSI_BOLD , & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_value: tmp=secstrcat(tmp, ANSI_RED , & rendersize_tmp); tmp=secstrcat(tmp, " found: ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_expected: tmp=secstrcat(tmp, ANSI_BLUE, & rendersize_tmp); tmp=secstrcat(tmp, " expected: " , & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_hard_error: tmp=secstrcat(tmp, ANSI_RED_BOLD , & rendersize_tmp); tmp=secstrcat(tmp, "(HE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_error: tmp=secstrcat(tmp, ANSI_RED , & rendersize_tmp); tmp=secstrcat(tmp, "(EE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_error_description: tmp=secstrcat(tmp, ANSI_RED , & rendersize_tmp); tmp=secstrcat(tmp, " ", & rendersize_tmp ); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_warning: tmp=secstrcat(tmp, ANSI_GREY , & rendersize_tmp); tmp=secstrcat(tmp, "(WW)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_logicalor_error: tmp=secstrcat(tmp, ANSI_YELLOW , & rendersize_tmp); tmp=secstrcat(tmp, "(LE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_file: res=secstrcat(res, "file: ", & rendersize_res ); res=secstrcat(res, ANSI_BLUE_BOLD, & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, ANSI_NORMAL , & rendersize_res); res=secstrcat(res, "\n", & rendersize_res); break; case rm_lineno: tmp=secstrcat(tmp, ANSI_GREY, & rendersize_tmp); tmp=secstrcat(tmp, " (lineno: ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); tmp=secstrcat(tmp, ")", & rendersize_tmp); break; case rm_endrule: case rm_endtiff: tmp=secstrcat(tmp, ANSI_NORMAL, & rendersize_tmp); tmp=secstrcat(tmp, "\n", & rendersize_tmp); /* copy tmp to res, reset tmp */ if ((is_valid == 0) && (is_quiet == 0)) { } else { res=secstrcat(res, tmp, & rendersize_res); } memset( tmp, '\0', rendersize_tmp); is_valid =1; break; case rm_is_valid: tmp=secstrcat(tmp, ANSI_GREEN_BOLD, & rendersize_tmp); tmp=secstrcat(tmp, "(./)", & rendersize_tmp); is_valid = 0; break; case rm_summary_valid: tmp=secstrcat(tmp, ANSI_GREEN_BOLD, & rendersize_tmp); tmp=secstrcat(tmp, "\n(./)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_summary_invalid: tmp=secstrcat(tmp, ANSI_RED_BOLD , & rendersize_tmp); tmp=secstrcat(tmp, "\n(EE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; default: tmp=secstrcat(tmp, ANSI_NORMAL , & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); } startp=startp->next; } res=secstrcat( res, ANSI_NORMAL, & rendersize_res); res=secstrcat( res, "\n", & rendersize_res); if (NULL != tmp) { free(tmp); } return res; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/renderer/check_renderer_default.c000066400000000000000000000115651327425157300246470ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include "check_renderer.h" #include const char * renderer_default ( const retmsg_t * ret, short int is_quiet ) { assert (ret != NULL); /* char * res = malloc( sizeof(char) * RENDERSIZE); if (NULL == res) { exit(could_not_allocate_memory); } memset( res, '\0', RENDERSIZE); */ char * res = calloc(RENDERSIZE, sizeof(char)); if (NULL == res) { exit(could_not_allocate_memory); } size_t rendersize_res = RENDERSIZE-1; /* char * tmp = malloc( sizeof(char) * RENDERSIZE); if (NULL == tmp) { exit(could_not_allocate_memory); } memset( tmp, '\0', RENDERSIZE); */ char * tmp = calloc( RENDERSIZE, sizeof(char)); if (NULL == tmp) { exit(could_not_allocate_memory); } size_t rendersize_tmp = RENDERSIZE-1; const retmsg_t * startp = ret; short int is_valid = 1; while (NULL != startp) { assert(startp->rm_msg != NULL); switch (startp->rm_type) { case rm_rule: tmp=secstrcat(tmp, "\t--> ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_tag: tmp=secstrcat(tmp, "\t", & rendersize_tmp ); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_mode: tmp=secstrcat(tmp, "\t", & rendersize_tmp ); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_value: tmp=secstrcat(tmp, "; found: ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_expected: tmp=secstrcat(tmp, "; expected: " , & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_hard_error: tmp=secstrcat(tmp, "(HE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_error: tmp=secstrcat(tmp, "(EE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_error_description: tmp=secstrcat(tmp, " ", & rendersize_tmp ); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_warning: tmp=secstrcat(tmp, "(WW)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_logicalor_error: tmp=secstrcat(tmp, "(LE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_file: res=secstrcat(res, "file: ", & rendersize_res ); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "\n", & rendersize_res); break; case rm_lineno: tmp=secstrcat(tmp, " (lineno: ", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); tmp=secstrcat(tmp, ")", & rendersize_tmp); break; case rm_endrule: case rm_endtiff: tmp=secstrcat(tmp, "\n", & rendersize_tmp); /* copy tmp to res, reset tmp */ if ((is_valid == 0) && (is_quiet == 0)) { } else { res=secstrcat(res, tmp, & rendersize_res); } memset( tmp, '\0', rendersize_tmp); is_valid =1; break; case rm_is_valid: tmp=secstrcat(tmp, "(./)", & rendersize_tmp); is_valid = 0; break; case rm_summary_valid: tmp=secstrcat(tmp, "\n(./)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; case rm_summary_invalid: tmp=secstrcat(tmp, "\n(EE)", & rendersize_tmp); tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); break; default: tmp=secstrcat(tmp, startp->rm_msg, & rendersize_tmp); } startp=startp->next; } res=secstrcat(res, "\n", & rendersize_res); if (NULL != tmp) { free(tmp); } return res; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/helper/renderer/check_renderer_xml.c000066400000000000000000000140541327425157300240170ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include "check_renderer.h" #include const char * renderer_xml ( const retmsg_t * ret, const char * xmlfile ) { assert (ret != NULL); if (xmlfile == NULL) { fprintf(stderr, "no given XML file for option '-x'\n"); exit(EXIT_FAILURE); } FILE *f = fopen(xmlfile, "w"); if (NULL == f) { fprintf(stderr, "Could not open file '%s' for writing\n", xmlfile); exit(EXIT_FAILURE); } /* char * res = malloc( sizeof(char) * RENDERSIZE); if (NULL == res) { exit(could_not_allocate_memory); } memset( res, '\0', RENDERSIZE); */ char * res = calloc(RENDERSIZE, sizeof(char)); if (NULL == res) { exit(could_not_allocate_memory); } size_t rendersize_res = RENDERSIZE-1; const retmsg_t * startp = ret; res=secstrcat(res, "\n", &rendersize_res); render_context_t is_valid=within_valid; while (NULL != startp) { assert(startp->rm_msg != NULL); switch (startp->rm_type) { case rm_rule: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, &rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_tag: res=secstrcat(res, "", & rendersize_res ); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_mode: res=secstrcat(res, "", & rendersize_res ); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_value: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_expected: res=secstrcat(res, "" , & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_hard_error: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); is_valid = within_harderror; break; case rm_error: if (strlen(startp->rm_msg) > 0) { res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); is_valid = within_summaryerror; } else { res=secstrcat(res, "", & rendersize_res); is_valid = within_error; } break; case rm_error_description: res=secstrcat(res, "", & rendersize_res ); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_warning: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); is_valid = within_error; break; case rm_logicalor_error: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); is_valid = within_error; break; case rm_file: res=secstrcat(res, "", & rendersize_res ); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "\n", & rendersize_res); break; case rm_lineno: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); break; case rm_endrule: case rm_endtiff: if (is_valid == within_valid) { res=secstrcat(res, "", & rendersize_res); } else if (is_valid == within_error) { res=secstrcat(res, "", & rendersize_res); } else if (is_valid == within_harderror) { res=secstrcat(res, "", & rendersize_res); } res=secstrcat(res, "\n", & rendersize_res); break; case rm_is_valid: res=secstrcat(res, "", & rendersize_res); is_valid = within_valid; break; case rm_summary_valid: case rm_summary_invalid: break; default: res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, startp->rm_msg, & rendersize_res); res=secstrcat(res, "", & rendersize_res); } startp=startp->next; } res=secstrcat(res, "", & rendersize_res); res=secstrcat(res, "\n", & rendersize_res); fprintf(f, "%s", res); fclose(f); memset( res, '\0', RENDERSIZE); return res; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/000077500000000000000000000000001327425157300165545ustar00rootroot00000000000000checkit_tiff-0.4.2/src/ifdrules/check_all_IFDs_are_word_aligned.c000066400000000000000000000016221327425157300250400ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #include /* check if IFDs are word aligned */ ret_t check_all_IFDs_are_word_aligned(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); uint32 ifd = get_ifd0_pos( ctif ); /* TODO: check all other IFDs, too */ if ( 0 != (ifd & 1)) { // FIXME: tif_fails? char array[VALUESTRLEN]; snprintf(array, sizeof(array), "offset of first IFD points to 0x%08x and is not word-aligned", ifd); ret = set_value_found_ret (&ret, array); ret.returncode = ifderror_offset_not_word_aligned; return ret; } ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/check_all_offsets_are_used_once_only.c000066400000000000000000000033041327425157300262720ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include /* check if offsets are used only once */ ret_t check_all_offsets_are_used_once_only(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); uint16 count = get_ifd0_count( ctif); if (count > 0) { uint16 tagidx; uint32 offsets[ count ]; uint32 tags[ count ]; int count_of_offsets = 0; int i; for (tagidx = 0; tagidx< count; tagidx++) { offsets[ tagidx ] = 0; tags[ tagidx ] = 0; } for (tagidx = 0; tagidx< count; tagidx++) { ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); if (ifd_entry.value_or_offset==is_offset) { uint32 offset = ifd_entry.data32offset; uint32 tag = TIFFGetRawTagListEntry( ctif, tagidx); for (i=0; i< count_of_offsets; i++) { if (offsets[ i ] == offset) { // FIXME: tif_fails? char array[TIFFAILSTRLEN]; snprintf(array, sizeof(array), "offset of tag %u (%s) points to %08x, which address is used previously by tag %u (%s)", tag, TIFFTagName(tag), offset, tags[i], TIFFTagName(tags[i]) ); ret.returncode = ifderror_offset_used_twice; ret = set_value_found_ret(&ret, array); return ret; } } offsets[ ++count_of_offsets ] = offset; tags[ count_of_offsets ] = tag; } } } ret.returncode=is_valid; /* valid also if count=0 */ return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/check_all_offsets_are_word_aligned.c000066400000000000000000000022451327425157300257260ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include /* check if offsets are word aligned */ ret_t check_all_offsets_are_word_aligned(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); int count = get_ifd0_count( ctif); int tagidx; for (tagidx = 0; tagidx< count; tagidx++) { ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); if (ifd_entry.value_or_offset==is_offset) { uint32 offset = ifd_entry.data32offset; if ( 0 != (offset & 1)) { uint32 tag = TIFFGetRawTagListEntry( ctif, tagidx); // FIXME: tif_fails? char array[TIFFAILSTRLEN]; snprintf(array, sizeof(array), "tag %u pointing to 0x%08x and is not word-aligned", tag, offset); ret = set_value_found_ret (&ret, array); ret.returncode = tagerror_offset_not_word_aligned; return ret; } } } ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/check_all_offsets_greater_zero.c000066400000000000000000000037751327425157300251420ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include /* check if offsets are greater zero */ ret_t check_all_offsets_are_greater_zero(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); int count = get_ifd0_count( ctif); int tagidx; for (tagidx = 0; tagidx< count; tagidx++) { ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); uint32 tag = TIFFGetRawTagListEntry( ctif, tagidx); if (ifd_entry.value_or_offset==is_offset || tag == TIFFTAG_EXIFIFD) { uint32 offset=0; if (ifd_entry.value_or_offset==is_offset) offset = ifd_entry.data32offset; else if (tag == TIFFTAG_EXIFIFD) { if (ifd_entry.count > 1) { ret = set_value_found_ret(&ret, int2str(ifd_entry.count)); ret.returncode = tagerror_expected_count_isgreaterone; return ret; } switch (ifd_entry.datatype) { case TIFF_LONG: { /* correct type */ offset = ifd_entry.data32; break; } default: { /* incorrect type for EXIF IFD */ ret = set_value_found_ret(&ret, TIFFTypeName(ifd_entry.datatype)); ret.returncode = tagerror_unexpected_type_found; return ret; /* break; */ }; } } /* end else if tag == TIFFTAG_EXIFIFD */ if ( 0 == offset) { // FIXME: tif_fails? char array[TIFFAILSTRLEN]; snprintf(array, sizeof(array), "tag %u pointing to 0x%08x", tag, offset); ret = set_value_found_ret (&ret, array); ret.returncode = tagerror_offset_is_zero; return ret; } } } ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/check_has_only_one_ifd.c000066400000000000000000000023011327425157300233500ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include /* check if only one IFD exists */ ret_t check_has_only_one_ifd(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); /* next commented lines, because TIFFNumberOfDirectories are in endless loop, * if the TIFF file from https://github.com/EasyinnovaSL/DPFManager/blob/develop/src/test/resources/IFD%20struct/Circular%20E.tif */ /* seek the image file directory (bytes 4-7) */ uint32 offset = get_ifd0_pos(ctif ); uint32 IFDn = get_next_ifd_pos( ctif, offset ); if (0 == IFDn) { ret.returncode=is_valid; return ret; } else { // FIXME: tif_fails? char array[TIFFAILSTRLEN]; snprintf(array, sizeof(array), "baseline TIFF should have only one IFD, but IFD0 at 0x%08x has pointer to IFDn 0x%08x", offset, IFDn ); ret = set_value_found_ret (&ret, array); ret.returncode = ifderror_multiple_ifd_detected; return ret; } } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/ifdrules/check_tagorder.c000066400000000000000000000050051327425157300216640ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #include ret_t check_tagorder(ctiff_t * ctif) { GET_EMPTY_RET(ret) tifp_check( ctif); if (has_sorted_tags != ctif->tagorder) { uint32 offset = get_ifd0_pos(ctif); int count = get_ifd0_count(ctif); /* read count of tags (2 Bytes) */ /* replace i/o operatrions with in-memory-operations */ uint8 * ifdentries = NULL; ifdentries = malloc ( sizeof(uint8) * 12 * count); if (NULL == ifdentries) { ret.returncode = could_not_allocate_memory; return ret; } if (ct_seek(ctif, offset+2, SEEK_SET) != (offset+2)) { char array[VALUESTRLEN]; snprintf(array, VALUESTRLEN, "%u bytes, errorcode=%i", offset+2, errno); ret = set_value_found_ret(&ret, array); ret.returncode = tiff_seek_error_header; if (NULL != ifdentries) free(ifdentries); return ret; } if ( ct_read( ctif, ifdentries, 12 * count) != 12*count ) { char array[VALUESTRLEN]; snprintf(array, VALUESTRLEN, "%i bytes, errorcode=%i", 12*count, errno); ret = set_value_found_ret(&ret, array); ret.returncode = tiff_read_error_header; return ret; } else { uint8 * e = ifdentries; uint16 lasttag = 0; for (int i = 0; i0 && lasttag >= tag) { // printf("tag idx=%i, tag=%u (0x%04x) (0x%02x) (0x%02x)\n", i, tag, tag, hi, lo); free( ifdentries ); // FIXME: tif_fails? char array[VALUESTRLEN]; snprintf(array, VALUESTRLEN, "previous tag:%u (%s) , actual tag:%u (%s) at pos %i of %i\n", lasttag, TIFFTagName(lasttag), tag, TIFFTagName(tag), i, count); ret = set_value_found_ret(&ret, array); ret.returncode = ifderror_tags_not_in_ascending_order; ctif->tagorder = has_unsorted_tags; return ret; } lasttag = tag; e+=10; } /* loop each tag until end or given tag found */ free( ifdentries ); ctif->tagorder = has_sorted_tags; } } ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/messages/000077500000000000000000000000001327425157300165465ustar00rootroot00000000000000checkit_tiff-0.4.2/src/messages/msg_parser.c000066400000000000000000000302501327425157300210540ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "config_parser.h" #include const char * get_parser_function_name( function_t f ) { switch (f) { case fc_true: return "fc_true"; break; case fc_false: return "fc_false"; break; case fc_tag_has_some_of_these_values: return "fc_tag_has_some_of_these_values"; break; case fc_tag_has_valuelist: return "fc_tag_has_valuelist"; break; case fc_tag_has_value_in_range: return "fc_tag_has_value_in_range"; break; case fc_tag_has_value: return "fc_tag_has_value"; break; case fc_tag_has_value_quiet: return "fc_tag_has_value_quiet"; break; case fc_tag: return "fc_tag"; break; case fc_tag_quiet: return "fc_tag_quiet"; break; case fc_notag: return "fc_notag"; break; case fc_tag_has_valid_type: return "fc_tag_has_valid_type"; break; case fc_datetime: return "fc_datetime"; break; case fc_icc: return "fc_icc"; break; case fc_has_only_one_ifd: return "fc_has_only_one_ifd"; break; case fc_tagorder: return "fc_tagorder"; break; case fc_tag_has_valid_asciivalue: return "fc_tag_has_valid_asciivalue"; break; case fc_tag_has_value_matching_regex: return "fc_tag_has_value_matching_regex"; break; case fc_all_offsets_are_word_aligned: return "fc_all_offsets_are_word_aligned"; break; case fc_all_offsets_are_used_once_only: return "fc_all_offsets_are_used_once_only"; break; case fc_all_IFDs_are_word_aligned: return "fc_all_IFDs_are_word_aligned"; break; case fc_internal_logic_combine_open: return "fc_internal_logic_combine_open"; break; case fc_internal_logic_combine_close: return "fc_internal_logic_combine_close"; break; case fc_all_offsets_are_not_zero: return "fc_all_offsets_are_not_zero"; break; case fc_dummy: return "fc_dummy"; break; } return "missed function description, should not occur"; } const char * get_parser_function_description( function_t f ) { switch (f) { case fc_true: return "true"; break; case fc_false: return "false"; break; case fc_tag_has_some_of_these_values: return "Tag should have one of these values:"; break; case fc_tag_has_valuelist: return "Tag should have a list of values"; break; case fc_tag_has_value_in_range: return "Tag should have a value in a range of"; break; case fc_tag_has_value: return "Tag should have one exact value."; break; case fc_tag_has_value_quiet: return "Tag should have one exact value."; break; case fc_tag: return "TIFF should contain this tag."; break; case fc_tag_quiet: return "TIFF should contain this tag."; break; case fc_notag: return "Tag needs to be whitelisted in configuration,"; break; case fc_tag_has_valid_type: return "Tag should have a valid and correct type."; break; case fc_datetime: return "DateTime tag should contain a valid value."; break; case fc_icc: return "ICC profile should be valid,"; break; case fc_has_only_one_ifd: return "TIFF should have just one IFD,"; break; case fc_tagorder: return "Tags should be sorted in ascending order,"; break; case fc_tag_has_valid_asciivalue: return "Tag should have valid ASCII value."; break; case fc_tag_has_value_matching_regex: return "Tag should have a value that matches the RegEx,"; break; case fc_all_offsets_are_word_aligned: return "All tag offsets should be word aligned,"; break; case fc_all_offsets_are_used_once_only: return "All offsets may only be used once,"; break; case fc_all_IFDs_are_word_aligned: return "All IFDs should be word aligned,"; break; case fc_internal_logic_combine_open: return "One or more conditions needs to be combined in a logical_or operation (open)"; break; case fc_internal_logic_combine_close: return "One or more conditions needs to be combined in a logical_or operation (close)"; break; case fc_all_offsets_are_not_zero: return "All tag offsets should be greater than zero,"; break; case fc_dummy: return "Dummy."; break; } return "missed function description, should not occur"; } const char * get_parser_error_description( returncode_t r ) { switch (r) { case is_valid: return "is valid"; break; /* no problems detected */ case calling_error_count_size: return "Internal error: function called with the wrong number of arguments."; break; /* a called function has wrong arguments */ case could_not_allocate_memory: return "Could not allocate memory."; break; /* malloc fails */ case could_not_print: return "Could not print"; break; /* snprintf, fprintf, print fails */ case should_not_occur: return "This should not occur."; break; /* dummy, for dead code */ case tagerror_expected_count_differs: return "unexpected tag value count"; break; /* if a tag reports count=m, but the rule expects count=n */ case tagerror_expected_count_iszero: return "Tag value count is zero, but expected to be greater than zero."; break; /* if a tag reports count=0, but the rule expects count=n */ case tagerror_expected_count_isgreaterone: return "Single value expected but list of values found."; break; case tagerror_value_differs: return "Unexpected tag value."; break; /* if a tag reports value=m, but the rule expects value=n */ case tagerror_unexpected_type_found: return "Unexpected tag type."; break; /* if a tag reports a type=m, but a type=n was expected */ case tagerror_datetime_not_plausible: return "DateTime value not plausible."; break; /* if a datetime tag has date values out of range */ case tagerror_datetime_wrong_format: return "DateTime tag has wrong format."; break; /* if a datetime tag has date with wrong format string */ case tagerror_datetime_wrong_size: return "DateTime tag has wrong size."; break; /* if a datetime tag has date with wrong size */ case tagerror_value_not_found: return "The value for this tag was not found."; break; /* if a value of a given tag is not found */ case tagwarn_type_of_unknown_tag_could_not_be_checked: return "The type of this unknown tag could not be checked: no rule defined."; break; /* there is no explicite type check defined yet */ case tag_exist: return "but isn't."; break; /* if a tag exists, but should not (only used by fc_notag) */ case tag_does_not_exist: return "Tag expected."; break; /* if a tag does not exist, but should (only used by fc_tag_quiet) */ case tagerror_encoded_as_value_excited_space: return "Tag value encoded as value but exceeded available space."; break; /* tag encoded as value instead as offset, but there is no enough space to hold it, pE. ICC-Profile encoded without offset */ case tagerror_pcre_nomatch: return "but doesn't."; break; /* regex does not match value */ case pcre_compile_error: return "The predefined Regex is invalid."; break; /* regex is wrong */ case tagerror_multiple_zeros_in_asciivalue: return "Multiple NULL-Bytes (\\0) found in ASCII value."; break; /* doubled \0 in string */ case tagerror_no_zero_as_end_of_string_in_asciivalue: return "Missed NULL-Byte (\\0) at end of ASCII value."; break; case tagerror_denominator_is_zero_in_fract: return "Denominator in fraction tag value is zero."; break; case ifderror_offset_used_twice: return "but this offset was used twice."; break; case ifderror_multiple_ifd_detected: return "but multiple IFDs were found."; break; case ifderror_tags_not_in_ascending_order: return "but aren't."; break; case tagerror_offset_not_word_aligned: return "but this one isn't."; break; case ifderror_offset_not_word_aligned: return "but aren't."; break; case iccerror_profileclass: return "but value found for ICC profileclass is not part of controlled vocabulary."; break; /* profile class ('%s'), should be one of following strings for device classes: 'scnr', 'mntr', 'prtr' or for profile classes: 'link', 'spac', 'abst', 'nmcl'" */ case iccerror_colorspacedata: return "but value found for ICC colorspacedata is not part of controlled vocabulary."; break; /* colorspace data ('%s'), should be one of following strings: 'XYZ ' 'Lab ' 'Luv ' 'YCbr' 'Yvx ' 'RGB ' 'GRAY' 'HSV ' 'HLS ' 'CMYK' 'CMY ' '2CLR' '3CLR' '4CLR' '5CLR' '6CLR' '7CLR' '8CLR' '9CLR' 'ACLR' 'BCLR' 'CCLR' 'DCLR' 'ECLR' 'FCLR'" */ case iccerror_connectionspacedata: return "but value found for ICC connectionspacedata is not part of controlled vocabulary."; break; /* "connection space data ('%s') should be one of following strings: 'XYZ ' 'Lab '" */ case iccerror_primaryplatformsignature: return "but value found for ICC primaryplatformsignature is not part of controlled vocabulary."; break; /* primary plattform signature ('%s') should be empty or one of following strings: 'APPL', 'MSFT', 'SGI ', 'SUNW', 'TGNT' */ case iccerror_header_1v43_2010: return "but invalid header in ICC profile of type 1v43_2010 found."; break; /* Invalid ICC profile 1v43_2010, see http://www.color.org/specification/ICC1v43_2010-12.pdf for details */ case iccerror_header_v240_v430: return "but invalid header in ICC profile of type v240_v430 found."; break; /* Invalid ICC profile ICC.1:2001-04, see http://www.color.org/ICC_Minor_Revision_for_Web.pdf for details */ case iccerror_header_v500_2016: return "but invalid header in ICC profile of type v500 found."; break; case iccerror_header_version_undefined: return "but invalid header in ICC profile with undefined version found."; break; case iccerror_header_version_outdated: return "but invalid header in ICC profile with outdated version found."; break; case iccerror_header_generic: return "but the ICC header is too short (size < 10)."; break; /* size < 10 */ case iccerror_preferredcmmtype: return "but value found for ICC preferredcmmtype is not part of controlled vocabulary."; break; /* preferred cmmtype ('%s') should be empty or (possibly, because ICC validation is alpha code) one of following strings: 'ADBE' 'ACMS' 'appl' 'CCMS' 'UCCM' 'UCMS' 'EFI ' 'FF ' 'EXAC' 'HCMM' 'argl' 'LgoS' 'HDM ' 'lcms' 'KCMS' 'MCML' 'WCS ' 'SIGN' 'RGMS' 'SICC' 'TCMM' '32BT' 'WTG ' 'zc00'" */ case iccerror_committed_size_differs : return "but ICC profile size given in ICC header differs from size given in TIFF tag."; break; case tiff_seek_error_header: return "Couldn't jump to TIFF header position (seek operation failed)."; break; case tiff_read_error_header: return "Couldn't read from TIFF header position (read operation failed)."; break; case tiff_seek_error_offset: return "Couldn't jump to TIFF data position (seek operation failed)."; break; case tiff_read_error_offset: return "Couldn't read from TIFF data position (seek operation failed)."; break; case tiff_byteorder_error: return "Unexpected byteorder."; break; /* not an expected byteorder found */ case tiff_ifd0_offset_must_be_greater_than_eight: return "The offset to IFD0 given in the TIFF header must be greater than 8 bytes."; break; /* must be greater than 8, because first 8 Bytes contains the TIFF header */ case code_error_streampointer_empty: return "Internal error: empty streampointer."; break; case code_error_filedescriptor_empty: return "Internal error: empty filedescriptor."; break; case code_error_ctif_empty: return "Internal error: unable to get ctif-structure"; break; case parser_error_wrong_function_found_in_parser_state_exe_stack: return "internal error: current stack function name not part of predefined name enumeration."; break; case parser_logicalor_error: return "internal error: parser error in logical_or rule"; break; case tagerror_expected_offsetdata: return "Expected offset data but found actual values encoded in tag."; break; case tagerror_count_results_in_offsets_overflow: return "Tag counts n elements, but resulting offset exceeds 4GB size"; break; case parser_logical_combine_open: return "internal parser state, combine multiple rules with logical or opened"; break; case parser_logical_combine_close: return "internal parser state, combine multiple rules with logical or closed"; break; case tagerror_offset_is_zero: return "but an offset zero is used."; break; } assert( r == is_valid ); /* missed error description, should not occur */ return "missed error description, should not occur"; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/messages/msg_tiffparse.c000066400000000000000000001363131327425157300215520ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see file LICENSE) * */ #include "msg_tiffparse.h" const char * TIFFTypeName( uint16 tagtype ) { switch (tagtype) { case TIFF_NOTYPE: return "NOTYPE"; break; case TIFF_BYTE: return "BYTE"; break; case TIFF_ASCII: return "ASCII"; break; case TIFF_SHORT: return "SHORT"; break; case TIFF_LONG: return "LONG"; break; case TIFF_RATIONAL: return "RATIONAL"; break; case TIFF_SBYTE: return "SBYTE"; break; case TIFF_UNDEFINED: return "UNDEFINED"; break; case TIFF_SSHORT: return "SSHORT"; break; case TIFF_SLONG: return "SLONG"; break; case TIFF_SRATIONAL: return "SRATIONAL"; break; case TIFF_FLOAT: return "FLOAT"; break; case TIFF_DOUBLE: return "DOUBLE"; break; case TIFF_IFD: return "IFD"; break; case TIFF_LONG8: return "LONG8"; break; case TIFF_SLONG8: return "SLONG8"; break; case TIFF_IFD8: return "IFD8"; break; default: return "unknown (unregistered) type"; break; } } const char * TIFFTagName( tag_t tag ) { switch (tag) { /* next lines from tiffdump.c */ /* 254 - 255, 0xfe - 0xff */ /* 254 */ case TIFFTAG_SUBFILETYPE: return ("SubFileType" ); /* 255 */ case TIFFTAG_OSUBFILETYPE: return ("OldSubFileType" ); /* 256 - 511, 0x100 - 0x1ff */ /* 256 */ case TIFFTAG_IMAGEWIDTH: return ("ImageWidth" ); /* 257 */ case TIFFTAG_IMAGELENGTH: return ("ImageLength" ); /* 258 */ case TIFFTAG_BITSPERSAMPLE: return ("BitsPerSample" ); /* 259 */ case TIFFTAG_COMPRESSION: return ("Compression" ); /* 262 */ case TIFFTAG_PHOTOMETRIC: return ("Photometric" ); /* 263 */ case TIFFTAG_THRESHHOLDING: return ("Threshholding" ); /* 264 */ case TIFFTAG_CELLWIDTH: return ("CellWidth" ); /* 265 */ case TIFFTAG_CELLLENGTH: return ("CellLength" ); /* 266 */ case TIFFTAG_FILLORDER: return ("FillOrder" ); /* 269 */ case TIFFTAG_DOCUMENTNAME: return ("DocumentName" ); /* 270 */ case TIFFTAG_IMAGEDESCRIPTION: return ("ImageDescription" ); /* 271 */ case TIFFTAG_MAKE: return ("Make" ); /* 272 */ case TIFFTAG_MODEL: return ("Model" ); /* 273 */ case TIFFTAG_STRIPOFFSETS: return ("StripOffsets" ); /* 274 */ case TIFFTAG_ORIENTATION: return ("Orientation" ); /* 277 */ case TIFFTAG_SAMPLESPERPIXEL: return ("SamplesPerPixel" ); /* 278 */ case TIFFTAG_ROWSPERSTRIP: return ("RowsPerStrip" ); /* 279 */ case TIFFTAG_STRIPBYTECOUNTS: return ("StripByteCounts" ); /* 280 */ case TIFFTAG_MINSAMPLEVALUE: return ("MinSampleValue" ); /* 281 */ case TIFFTAG_MAXSAMPLEVALUE: return ("MaxSampleValue" ); /* 282 */ case TIFFTAG_XRESOLUTION: return ("XResolution" ); /* 283 */ case TIFFTAG_YRESOLUTION: return ("YResolution" ); /* 284 */ case TIFFTAG_PLANARCONFIG: return ("PlanarConfig" ); /* 285 */ case TIFFTAG_PAGENAME: return ("PageName" ); /* 286 */ case TIFFTAG_XPOSITION: return ("XPosition" ); /* 287 */ case TIFFTAG_YPOSITION: return ("YPosition" ); /* 288 */ case TIFFTAG_FREEOFFSETS: return ("FreeOffsets" ); /* 289 */ case TIFFTAG_FREEBYTECOUNTS: return ("FreeByteCounts" ); /* 290 */ case TIFFTAG_GRAYRESPONSEUNIT: return ("GrayResponseUnit" ); /* 291 */ case TIFFTAG_GRAYRESPONSECURVE: return ("GrayResponseCurve" ); /* 292 */ case TIFFTAG_GROUP3OPTIONS: return ("Group3Options" ); /* 293 */ case TIFFTAG_GROUP4OPTIONS: return ("Group4Options" ); /* 296 */ case TIFFTAG_RESOLUTIONUNIT: return ("ResolutionUnit" ); /* 297 */ case TIFFTAG_PAGENUMBER: return ("PageNumber" ); /* 300 */ case TIFFTAG_COLORRESPONSEUNIT: return ("ColorResponseUnit" ); /* 301 */ case TIFFTAG_TRANSFERFUNCTION: return ("TransferFunction" ); /* 305 */ case TIFFTAG_SOFTWARE: return ("Software" ); /* 306 */ case TIFFTAG_DATETIME: return ("DateTime" ); /* 315 */ case TIFFTAG_ARTIST: return ("Artist" ); /* 316 */ case TIFFTAG_HOSTCOMPUTER: return ("HostComputer" ); /* 317 */ case TIFFTAG_PREDICTOR: return ("Predictor" ); /* 318 */ case TIFFTAG_WHITEPOINT: return ("Whitepoint" ); /* 319 */ case TIFFTAG_PRIMARYCHROMATICITIES: return ("PrimaryChromaticities" ); /* 320 */ case TIFFTAG_COLORMAP: return ("Colormap" ); /* 321 */ case TIFFTAG_HALFTONEHINTS: return ("HalftoneHints" ); /* 322 */ case TIFFTAG_TILEWIDTH: return ("TileWidth" ); /* 323 */ case TIFFTAG_TILELENGTH: return ("TileLength" ); /* 324 */ case TIFFTAG_TILEOFFSETS: return ("TileOffsets" ); /* 325 */ case TIFFTAG_TILEBYTECOUNTS: return ("TileByteCounts" ); /* 326 */ case TIFFTAG_BADFAXLINES: return ("BadFaxLines" ); /* 327 */ case TIFFTAG_CLEANFAXDATA: return ("CleanFaxData" ); /* 328 */ case TIFFTAG_CONSECUTIVEBADFAXLINES: return ("ConsecutiveBadFaxLines" ); /* 330 */ case TIFFTAG_SUBIFD: return ("SubIFD" ); /* 332 */ case TIFFTAG_INKSET: return ("InkSet" ); /* 333 */ case TIFFTAG_INKNAMES: return ("InkNames" ); /* 334 */ case TIFFTAG_NUMBEROFINKS: return ("NumberOfInks" ); /* 336 */ case TIFFTAG_DOTRANGE: return ("DotRange" ); /* 337 */ case TIFFTAG_TARGETPRINTER: return ("TargetPrinter" ); /* 338 */ case TIFFTAG_EXTRASAMPLES: return ("ExtraSamples" ); /* 339 */ case TIFFTAG_SAMPLEFORMAT: return ("SampleFormat" ); /* 340 */ case TIFFTAG_SMINSAMPLEVALUE: return ("SMinSampleValue" ); /* 341 */ case TIFFTAG_SMAXSAMPLEVALUE: return ("SMaxSampleValue" ); /* 347 */ case TIFFTAG_JPEGTABLES: return ("JPEGTables" ); /* 400 */ case TIFFTAG_GLOBALPARAMETERSIFD: return ("GLOBALPARAMETERSIFD"); /* 401 */ case TIFFTAG_PROFILETYPE: return ("PROFILETYPE"); /* 402 */ case TIFFTAG_FAXPROFILE: return ("FAXPROFILE"); /* 403 */ case TIFFTAG_CODINGMETHODS: return ("CODINGMETHODS"); /* 404 */ case TIFFTAG_VERSIONYEAR: return ("VERSIONYEAR"); /* 405 */ case TIFFTAG_MODENUMBER: return ("MODENUMBER"); /* 433 */ case TIFFTAG_DECODE: return ("DECODE"); /* 434 */ case TIFFTAG_IMAGEBASECOLOR: return ("IMAGEBASECOLOR"); /* 435 */ case TIFFTAG_T82OPTIONS: return ("T82OPTIONS"); /* 512 - 767, 0x200 - 0x2ff */ /* 512 */ case TIFFTAG_JPEGPROC: return ("JPEGProcessingMode" ); /* 513 */ case TIFFTAG_JPEGIFOFFSET: return ("JPEGInterchangeFormat" ); /* 514 */ case TIFFTAG_JPEGIFBYTECOUNT: return ("JPEGInterchangeFormatLength" ); /* 515 */ case TIFFTAG_JPEGRESTARTINTERVAL: return ("JPEGRestartInterval" ); /* 517 */ case TIFFTAG_JPEGLOSSLESSPREDICTORS: return ("JPEGLosslessPredictors" ); /* 518 */ case TIFFTAG_JPEGPOINTTRANSFORM: return ("JPEGPointTransform" ); /* 519 */ case TIFFTAG_JPEGQTABLES: return ("JPEGQTables" ); /* 520 */ case TIFFTAG_JPEGDCTABLES: return ("JPEGDCTables" ); /* 521 */ case TIFFTAG_JPEGACTABLES: return ("JPEGACTables" ); /* 529 */ case TIFFTAG_YCBCRCOEFFICIENTS: return ("YCbCrCoefficients" ); /* 530 */ case TIFFTAG_YCBCRSUBSAMPLING: return ("YCbCrSubsampling" ); /* 531 */ case TIFFTAG_YCBCRPOSITIONING: return ("YCbCrPositioning" ); /* 532 */ case TIFFTAG_REFERENCEBLACKWHITE: return ("ReferenceBlackWhite" ); /* 559 */ case TIFFTAG_STRIPROWCOUNTS: return ("StripRowCounts"); /* 700 */ case TIFFTAG_XMLPACKET: return ("XMP"); /* 20507 */ case 20507: return ("unofficial EXIF ThumbnailData (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20515 */ case 20515: return ("unofficial EXIF ThumbnailCompression (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20525 */ case 20525: return ("unofficial EXIF ThumbnailResolutionX (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20526 */ case 20526: return ("unofficial EXIF ThumbnailResolutionY (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20528 */ case 20528: return ("unofficial EXIF ThumbnailResolutionUnit (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20624 */ case 20624: return ("unofficial EXIF LuminanceTable (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 20625 */ case 20625: return ("unofficial EXIF ChrominanceTable (poss. Olympus)"); /* see http://www.stefanheymann.de/homegallery/exif-felder.htm, but not in Exif2.3 standard */ /* 32768 -, 0x8000 - */ /* 32768 */ case 32768: return ("OLD BOGUS Matteing tag" ); /* 32781 */ case TIFFTAG_OPIIMAGEID: return ("OpiImageId"); /* 32835 */ case 32835: return ("XIS private compression scheme tag"); /* see code line 97ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 32836 */ case 32836: return ("XIS private compression scheme tag"); /* see code line 97ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 32837 */ case 32837: return ("XIS private compression scheme tag"); /* see code line 97ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 32838 */ case 32838: return ("XIS private compression scheme tag"); /* see code line 97ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 32839 */ case 32839: return ("XIS private compression scheme tag"); /* see code line 97ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* next 5 lines WANG TIFF */ /* 32931 */ case 32931: return ("TIFF HiTIFF / Wang TIFF"); /* https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/oiwh/include/tifftags.h */ /* 32932 */ case 32932: return ("TIFF annotation data / Wang TIFF"); /* http://web.archive.org/web/20050309141348/http://www.kofile.com/support%20pro/faqs/annospec.htm, for full explanation, see http://web.archive.org/web/20030124024322/http://www5.eistream.com/support_pro/faqs/annospec.htm */ /* 32933 */ case 32933: return ("unknown Wang TIFF"); /* 32934 */ case 32934: return ("Offset to Page Control Structure / Wang TIFF"); /* https://groups.yahoo.com/neo/groups/tiff/conversations/messages/1968 */ /* 32935 */ case 32935: return ("TOC / Wang TIFF"); /* https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/oiwh/include/tifftags.h */ /* 32952 */ case 32952: return ("unknown Ig (Island Graphics)" ); /* http://fileformats.archiveteam.org/wiki/Island_Graphics_TIFF */ /* 32953 */ case TIFFTAG_REFPTS: return ("IgReferencePoints (Island Graphics)" ); /* 32954 */ case TIFFTAG_REGIONTACKPOINT: return ("IgRegionTackPoint (Island Graphics)" ); /* 32955 */ case TIFFTAG_REGIONWARPCORNERS: return ("IgRegionWarpCorners (Island Graphics)" ); /* 32956 */ case TIFFTAG_REGIONAFFINE: return ("IgRegionAffine (Island Graphics)" ); /* 32970 */ case 32970: return ("temperature (COMPIX)"); /* http://www.compix.com/fileformattif.htm */ /* 32971 */ case 32971: return ("Zoombox (COMPIX)"); /* http://www.compix.com/fileformattif.htm */ /* 32972 */ case 32972: return ("WinTES (COMPIX)"); /* http://www.compix.com/fileformattif.htm */ /* 32995 */ case TIFFTAG_MATTEING: return ("OBSOLETE Matteing (Silicon Graphics)" ); /* 32996 */ case TIFFTAG_DATATYPE: return ("OBSOLETE DataType (Silicon Graphics)" ); /* 32997 */ case TIFFTAG_IMAGEDEPTH: return ("ImageDepth (Silicon Graphics)" ); /* 32998 */ case TIFFTAG_TILEDEPTH: return ("TileDepth (Silicon Graphics)" ); /* 33300 */ case TIFFTAG_PIXAR_IMAGEFULLWIDTH: return ("PIXAR_IMAGEFULLWIDTH"); /* 33301 */ case TIFFTAG_PIXAR_IMAGEFULLLENGTH: return ("PIXAR_IMAGEFULLLENGTH"); /* 33302 */ case TIFFTAG_PIXAR_TEXTUREFORMAT: return ("PIXAR_TEXTUREFORMAT"); /* 33303 */ case TIFFTAG_PIXAR_WRAPMODES: return ("PIXAR_WRAPMODES"); /* 33304 */ case TIFFTAG_PIXAR_FOVCOT: return ("PIXAR_FOVCOT"); /* 33305 */ case TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN: return ("PIXAR_MATRIX_WORLDTOSCREEN"); /* 33306 */ case TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA: return ("PIXAR_MATRIX_WORLDTOCAMERA"); /* 33405 */ case TIFFTAG_WRITERSERIALNUMBER: return ("Kodak serial number"); /* 33421 */ case 33421: return ("CFAREPEATPATTERNDIM"); /* 33422 */ case 33422: return ("CFAPATTERN"); /* 33423 */ case 33423: return ("BatteryLevel (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 33424 */ case 33424: return ("Kodak IFD"); /* http://perldoc.net/Image/ExifTool/TagNames.pod#Unknown%20Tags */ /* 33432 */ case TIFFTAG_COPYRIGHT: return ("Copyright" ); /* 33434 */ case 33434: return ("EXIF ExposureTime"); /* EXIF, Exposure time, given in seconds. */ /* 33437 */ case 33437: return ("EXIF FNumber"); /* EXIF, The F number. */ /* 33445 */ case 33445: return ("MD_Filetag"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf or http://www.awaresystems.be/imaging/tiff/tifftags/docs/gel.html*/ /* 33446 */ case 33446: return ("MD_ScalePixel"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33447 */ case 33447: return ("MD_Colortable"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33448 */ case 33448: return ("MD_LabName"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33449 */ case 33449: return ("MD_SampleInfo"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33450 */ case 33450: return ("MD_PrepDate"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33451 */ case 33451: return ("MD_PrepTime"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33452 */ case 33452: return ("MD_FileUnits"); /* http://research.stowers-institute.org/mcm/efg/ScientificSoftware/Utility/TiffTags/GEL-FileFormat.pdf */ /* 33471 */ case 33471: return ("SIS Init Standard Metadata (Olympus)"); /* https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/SISReader.java */ /* 33550 */ case 33550: return ("GeoTIFF ModelPixelScale"); /* http://web.archive.org/web/20160407200550/http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.1 */ /* 33560 */ case 33560: return ("SIS Offset Metadata (Olympus)"); /* https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/SISReader.java */ /* 33609 */ case 33609: return ("Component subsample CMYK/YCBCR (WangTIFF)"); /* line 182, https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 33628 */ case 33628: return ("MetaMorph Stack Image UIC1"); /* see: ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc, but also read comments in https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/PrairieReader.java */ /* 33629 */ case 33629: return ("MetaMorph Stack Image UIC2"); /* see: ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc, but also read comments in https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/PrairieReader.java */ /* 33630 */ case 33630: return ("MetaMorph Stack Image UIC3"); /* see: ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc, but also read comments in https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/PrairieReader.java */ /* 33631 */ case 33631: return ("MetaMorph Stack Image UIC4"); /* see: ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc */ /* 33723 */ case TIFFTAG_RICHTIFFIPTC: return ("RichTIFFIPTC / NAA"); /* see ISO12234-2:2001 for TIFF/EP */ /* 33918 */ case 33918: return ("INGR Packet Data Tag (Intergraph)"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 33919 */ case 33919: return ("INGR Flag Registers (Intergraph)"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 33920 */ case 33920: return ("IrasB Transformation Matrix / obsolete GeoTIFF IntergraphMatrixTag (Intergraph)"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 33921 */ case 33921: return ("Georeferencing Tag / obsolete (Intergraph)"); /* see http://www.awaresystems.be/imaging/tiff/tifftags/docs/intergraph.html */ /* 33922 */ case 33922: return ("GeoTIFF ModelTiepointTag (Intergraph)"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 33923 */ case 33923: return ("Leica Magic Tag"); /* see https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/LeicaReader.java */ /* 33979 */ case 33979: return ("XIS private tag"); /* see code line 89ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 33980 */ case 33980: return ("XIS private tag"); /* see code line 89ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 33981 */ case 33981: return ("XIS private tag"); /* see code line 89ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 33982 */ case 33982: return ("XIS private tag"); /* see code line 89ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 33983 */ case 33983: return ("XIS private tag"); /* see code line 89ff. at https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiff.h */ /* 34016 */ case TIFFTAG_IT8SITE: return ("IT8SITE"); /* 34017 */ case TIFFTAG_IT8COLORSEQUENCE: return ("IT8COLORSEQUENCE"); /* 34018 */ case TIFFTAG_IT8HEADER: return ("IT8HEADER"); /* 34019 */ case TIFFTAG_IT8RASTERPADDING: return ("IT8RASTERPADDING"); /* 34020 */ case TIFFTAG_IT8BITSPERRUNLENGTH: return ("IT8BITSPERRUNLENGTH"); /* 34021 */ case TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH: return ("IT8BITSPEREXTENDEDRUNLENGTH"); /* 34022 */ case TIFFTAG_IT8COLORTABLE: return ("IT8COLORTABLE"); /* 34023 */ case TIFFTAG_IT8IMAGECOLORINDICATOR: return ("IT8IMAGECOLORINDICATOR"); /* 34024 */ case TIFFTAG_IT8BKGCOLORINDICATOR: return ("IT8BKGCOLORINDICATOR"); /* 34025 */ case TIFFTAG_IT8IMAGECOLORVALUE: return ("IT8IMAGECOLORVALUE"); /* 34026 */ case TIFFTAG_IT8BKGCOLORVALUE: return ("IT8BKGCOLORVALUE"); /* 34027 */ case TIFFTAG_IT8PIXELINTENSITYRANGE: return ("IT8PIXELINTENSITYRANGE"); /* 34028 */ case TIFFTAG_IT8TRANSPARENCYINDICATOR: return ("IT8TRANSPARENCYINDICATOR"); /* 34029 */ case TIFFTAG_IT8COLORCHARACTERIZATION: return ("IT8COLORCHARACTERIZATION"); /* 34030 */ case TIFFTAG_IT8HCUSAGE: return ("IT8HCUSAGE"); /* 34031 */ case TIFFTAG_IT8TRAPINDICATOR: return ("IT8TRAPINDICATOR"); /* 34032 */ case TIFFTAG_IT8CMYKEQUIVALENT: return ("IT8CMYKEQUIVALENT"); /* 34152 */ case 34152: return ("RichTIFFIPTC / NAA (deprecated)"); /* same as in Tag 33723, see http://www.nilesritter.com/webdocs/tiff/richtiff.html */ /* 34232 */ case TIFFTAG_FRAMECOUNT: return ("FRAMECOUNT"); /* 34264 */ case 34264: return ("Geotiff ModelTransformationTag (JPL Carto Group)"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 34310 */ case 34310: return ("Leaf MOS PKTS tag (Raw camera)"); /* see http://fileformats.archiveteam.org/wiki/Leaf_MOS */ /* 34361 */ case 34361: return ("MMHeader (Olympus Fluoview or Andor Bio-imaging Division)"); /* https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/FluoviewReader.java */ /* 34362 */ case 34362: return ("MMStamp (Olympus Fluoview or Andor Bio-imaging Division)"); /* https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/FluoviewReader.java */ /* 34377 */ case TIFFTAG_PHOTOSHOP: return ("Photoshop Image Ressources"); /* see http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577413_pgfId-1039502, also see paragraph "Photoshop Image Resource Metadata Structure" in http://help.accusoft.com/ImageGear/v17.2/Windows/DLL/topic755.html or http://fileformats.archiveteam.org/wiki/Photoshop_Image_Resources, this points to http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037685 and http://www.awaresystems.be/imaging/tiff/tifftags/docs/photoshopthumbnail.html*/ /* 34665 */ case TIFFTAG_EXIFIFD: return ("EXIFIFDOffset"); /* 34675 */ case TIFFTAG_ICCPROFILE: return ("ICC Profile" ); /* 34730 */ case 34730: return ("Annotation Offsets (Wang TIFF)"); /* line 134, https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiffint.h */ /* 34731 */ case 34731: return ("Mask SUBIFDs (Wang TIFF)"); /* line 135, https://github.com/gasgas4/NT_4.0_SourceCode/blob/master/nt4/private/wangview/xfilexr/include/tiffint.h */ /* 34732 */ case TIFFTAG_IMAGELAYER: return ("ImageLayer"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag, see RFC2301*/ /* 34735 */ case 34735: return ("Geotiff GeoKeyDirectoryTag (SPOT)"); /* http://web.archive.org/web/20160407200550/http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.1 */ /* 34736 */ case 34736: return ("Geotiff GeoDoubleParamsTag (SPOT)"); /* http://web.archive.org/web/20160407200550/http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.1 */ /* 34737 */ case 34737: return ("Geotiff GeoAsciiParamsTag (SPOT)"); /* http://web.archive.org/web/20160407200550/http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.1 */ /* 34750 */ case TIFFTAG_JBIGOPTIONS: return ("JBIG Options" ); /* 34820 */ case 34820: return ("EMC/PixTool SpecificTag"); /* thgere is more informatioon about meaning needed. If tag exists, there was string "Untitled" encoded (as binary) */ /* 34850 */ case 34850: return ("EXIF ExposureProgram"); /* EXIF, The class of the program used by the camera to set exposure when the picture is taken. */ /* 34852 */ case 34852: return ("EXIF SpectralSensitivity"); /* EXIF, Indicates the spectral sensitivity of each channel of the camera used. */ /* 34853 */ case TIFFTAG_GPSIFD: return ("GPSIFD or Olympus SIS TAG2"); /* for Olympus, see https://github.com/openmicroscopy/bioformats/blob/v5.2.4/components/formats-gpl/src/loci/formats/in/SISReader.java */ /* 34855 */ case 34855: return ("EXIF ISOSpeedRatings"); /* EXIF, Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232. */ /* 34856 */ case 34856: return ("EXIF OECF"); /* EXIF, Indicates the Opto-Electric Conversion Function (OECF) specified in ISO 14524. */ /* 34857 */ case 34857: return ("Interlace (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 34858 */ case 34858: return ("TimeZoneOffset (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 34859 */ case 34859: return ("SelfTimerMode (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 34908 */ case TIFFTAG_FAXRECVPARAMS: return ("HylaFax FaxRecvParams"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 34909 */ case TIFFTAG_FAXSUBADDRESS: return ("HylaFax FaxSubAdress"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 34910 */ case TIFFTAG_FAXRECVTIME: return ("HylaFax FaxRecvTime"); /* see http://www.rastermaster.com/RasterMaster%20DLL%20manual/WebHelp/Content/aptifftagswide.htm for explanation of tag*/ /* 36864 */ case 36864: return ("EXIF ExifVersion"); /* EXIF, The version of the supported Exif standard. */ /* 36867 */ case 36867: return ("EXIF DateTimeOriginal"); /* EXIF, The date and time when the original image data was generated. */ /* 36868 */ case 36868: return ("EXIF DateTimeDigitized"); /* EXIF, The date and time when the image was stored as digital data. */ /* 37121 */ case 37121: return ("EXIF ComponentsConfiguration"); /* EXIF, Specific to compressed data; specifies the channels and complements PhotometricInterpretation */ /* 37122 */ case 37122: return ("EXIF CompressedBitsPerPixel"); /* EXIF, Specific to compressed data; states the compressed bits per pixel. */ /* 37377 */ case 37377: return ("EXIF ShutterSpeedValue"); /* EXIF, Shutter speed. */ /* 37378 */ case 37378: return ("EXIF ApertureValue"); /* EXIF, The lens aperture. */ /* 37379 */ case 37379: return ("EXIF BrightnessValue"); /* EXIF, The value of brightness. */ /* 37380 */ case 37380: return ("EXIF ExposureBiasValue"); /* EXIF, The exposure bias. */ /* 37381 */ case 37381: return ("EXIF MaxApertureValue"); /* EXIF, The smallest F number of the lens. */ /* 37382 */ case 37382: return ("EXIF SubjectDistance"); /* EXIF, The distance to the subject, given in meters. */ /* 37383 */ case 37383: return ("EXIF MeteringMode"); /* EXIF, The metering mode. */ /* 37384 */ case 37384: return ("EXIF LightSource"); /* EXIF, The kind of light source. */ /* 37385 */ case 37385: return ("EXIF Flash"); /* EXIF, Indicates the status of flash when the image was shot. */ /* 37386 */ case 37386: return ("EXIF FocalLength"); /* EXIF, The actual focal length of the lens, in mm. */ /* 37387 */ case 37387: return ("FlashEnergy (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37388 */ case 37388: return ("SpatialFrequencyResponse (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37389 */ case 37389: return ("Noise (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37390 */ case 37390: return ("FocalPlaneXResolution (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37391 */ case 37391: return ("FocalPlaneYResolution (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37392 */ case 37392: return ("FocalPlaneResolutionUnit (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37393 */ case 37393: return ("ImageNumber (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37394 */ case 37394: return ("SecurityClassification (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37395 */ case 37395: return ("ImageHistory (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37396 */ case 37396: return ("EXIF SubjectArea"); /* EXIF, Indicates the location and area of the main subject in the overall scene. Similar with SubjectLocation at TIFF/EP */ /* 37397 */ case 37397: return ("ExposureIndex (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37398 */ case 37398: return ("TIFF/EP StandardID"); /* see TIFF/EP ISO12234-2:2001, see http://fileformats.archiveteam.org/wiki/TIFF/EP */ /* 37399 */ case 37399: return ("Sensing Method (TIFF/EP)"); /* see ISO12234-2:2001 for TIFF/EP */ /* 37400 */ case 37400: return ("old Kodak KDC"); /* see #include #include #define YYRULECOUNT 43 #ifndef YY_MALLOC #define YY_MALLOC(C, N) malloc(N) #endif #ifndef YY_REALLOC #define YY_REALLOC(C, P, N) realloc(P, N) #endif #ifndef YY_FREE #define YY_FREE(C, P) free(P) #endif #ifndef YY_LOCAL #define YY_LOCAL(T) static T #endif #ifndef YY_ACTION #define YY_ACTION(T) static T #endif #ifndef YY_RULE #define YY_RULE(T) static T #endif #ifndef YY_PARSE #define YY_PARSE(T) T #endif #ifndef YYPARSE #define YYPARSE yyparse #endif #ifndef YYPARSEFROM #define YYPARSEFROM yyparsefrom #endif #ifndef YYRELEASE #define YYRELEASE yyrelease #endif #ifndef YY_BEGIN #define YY_BEGIN ( yy->__begin= yy->__pos, 1) #endif #ifndef YY_END #define YY_END ( yy->__end= yy->__pos, 1) #endif #ifdef YY_DEBUG # define yyprintf(args) fprintf args #else # define yyprintf(args) #endif #ifndef YYSTYPE #define YYSTYPE int #endif #ifndef YY_STACK_SIZE #define YY_STACK_SIZE 128 #endif #ifndef YY_BUFFER_SIZE #define YY_BUFFER_SIZE 1024 #endif #ifndef YY_PART typedef struct _yycontext yycontext; typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng); typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; struct _yycontext { char *__buf; int __buflen; int __pos; int __limit; char *__text; int __textlen; int __begin; int __end; int __textmax; yythunk *__thunks; int __thunkslen; int __thunkpos; YYSTYPE __; YYSTYPE *__val; YYSTYPE *__vals; int __valslen; #ifdef YY_CTX_MEMBERS YY_CTX_MEMBERS #endif }; #ifdef YY_CTX_LOCAL #define YY_CTX_PARAM_ yycontext *yyctx, #define YY_CTX_PARAM yycontext *yyctx #define YY_CTX_ARG_ yyctx, #define YY_CTX_ARG yyctx #ifndef YY_INPUT #define YY_INPUT(yy, buf, result, max_size) \ { \ int yyc= getchar(); \ result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ yyprintf((stderr, "<%c>", yyc)); \ } #endif #else #define YY_CTX_PARAM_ #define YY_CTX_PARAM #define YY_CTX_ARG_ #define YY_CTX_ARG yycontext _yyctx= { 0, 0 }; yycontext *yyctx= &_yyctx; #ifndef YY_INPUT #define YY_INPUT(buf, result, max_size) \ { \ int yyc= getchar(); \ result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ yyprintf((stderr, "<%c>", yyc)); \ } #endif #endif YY_LOCAL(int) yyrefill(yycontext *yy) { int yyn; while (yy->__buflen - yy->__pos < 512) { yy->__buflen *= 2; yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen); } #ifdef YY_CTX_LOCAL YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); #else YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); #endif if (!yyn) return 0; yy->__limit += yyn; return 1; } YY_LOCAL(int) yymatchDot(yycontext *yy) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; ++yy->__pos; return 1; } YY_LOCAL(int) yymatchChar(yycontext *yy, int c) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; if ((unsigned char)yy->__buf[yy->__pos] == c) { ++yy->__pos; yyprintf((stderr, " ok yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); return 1; } yyprintf((stderr, " fail yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); return 0; } YY_LOCAL(int) yymatchString(yycontext *yy, const char *s) { int yysav= yy->__pos; while (*s) { if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; if (yy->__buf[yy->__pos] != *s) { yy->__pos= yysav; return 0; } ++s; ++yy->__pos; } return 1; } YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits) { int c; if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; c= (unsigned char)yy->__buf[yy->__pos]; if (bits[c >> 3] & (1 << (c & 7))) { ++yy->__pos; yyprintf((stderr, " ok yymatchClass @ %s\n", yy->__buf+yy->__pos)); return 1; } yyprintf((stderr, " fail yymatchClass @ %s\n", yy->__buf+yy->__pos)); return 0; } YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end) { while (yy->__thunkpos >= yy->__thunkslen) { yy->__thunkslen *= 2; yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen); } yy->__thunks[yy->__thunkpos].begin= begin; yy->__thunks[yy->__thunkpos].end= end; yy->__thunks[yy->__thunkpos].action= action; ++yy->__thunkpos; } YY_LOCAL(int) yyText(yycontext *yy, int begin, int end) { int yyleng= end - begin; if (yyleng <= 0) yyleng= 0; else { while (yy->__textlen < (yyleng + 1)) { yy->__textlen *= 2; yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen); } memcpy(yy->__text, yy->__buf + begin, yyleng); } yy->__text[yyleng]= '\0'; return yyleng; } YY_LOCAL(void) yyDone(yycontext *yy) { int pos; for (pos= 0; pos < yy->__thunkpos; ++pos) { yythunk *thunk= &yy->__thunks[pos]; int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin; yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, yy->__text)); thunk->action(yy, yy->__text, yyleng); } yy->__thunkpos= 0; } YY_LOCAL(void) yyCommit(yycontext *yy) { if ((yy->__limit -= yy->__pos)) { memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit); } yy->__begin -= yy->__pos; yy->__end -= yy->__pos; yy->__pos= yy->__thunkpos= 0; } YY_LOCAL(int) yyAccept(yycontext *yy, int tp0) { if (tp0) { fprintf(stderr, "accept denied at %d\n", tp0); return 0; } else { yyDone(yy); yyCommit(yy); } return 1; } YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count) { yy->__val += count; while (yy->__valslen <= yy->__val - yy->__vals) { long offset= yy->__val - yy->__vals; yy->__valslen *= 2; yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen); yy->__val= yy->__vals + offset; } } YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count) { yy->__val -= count; } YY_LOCAL(void) yySet(yycontext *yy, char *text, int count) { yy->__val[count]= yy->__; } #endif /* YY_PART */ #define YYACCEPT yyAccept(yy, yythunkpos0) YY_RULE(int) yy_EscapedPCRE(yycontext *yy); /* 43 */ YY_RULE(int) yy_PCRE(yycontext *yy); /* 42 */ YY_RULE(int) yy_Value(yycontext *yy); /* 41 */ YY_RULE(int) yy_ValueList(yycontext *yy); /* 40 */ YY_RULE(int) yy_Digit(yycontext *yy); /* 39 */ YY_RULE(int) yy_Iccprofile(yycontext *yy); /* 38 */ YY_RULE(int) yy_Datetime(yycontext *yy); /* 37 */ YY_RULE(int) yy_ValueReference(yycontext *yy); /* 36 */ YY_RULE(int) yy_Dot(yycontext *yy); /* 35 */ YY_RULE(int) yy_OptDepends(yycontext *yy); /* 34 */ YY_RULE(int) yy_IfDepends(yycontext *yy); /* 33 */ YY_RULE(int) yy_Space(yycontext *yy); /* 32 */ YY_RULE(int) yy_TagReference(yycontext *yy); /* 31 */ YY_RULE(int) yy_Content(yycontext *yy); /* 30 */ YY_RULE(int) yy_Requirements(yycontext *yy); /* 29 */ YY_RULE(int) yy_Semicolon(yycontext *yy); /* 28 */ YY_RULE(int) yy_Tag(yycontext *yy); /* 27 */ YY_RULE(int) yy_Colon(yycontext *yy); /* 26 */ YY_RULE(int) yy_PrintableAscii(yycontext *yy); /* 25 */ YY_RULE(int) yy_RegEx(yycontext *yy); /* 24 */ YY_RULE(int) yy_NTupel(yycontext *yy); /* 23 */ YY_RULE(int) yy_Number(yycontext *yy); /* 22 */ YY_RULE(int) yy_Only(yycontext *yy); /* 21 */ YY_RULE(int) yy_Range(yycontext *yy); /* 20 */ YY_RULE(int) yy_Any(yycontext *yy); /* 19 */ YY_RULE(int) yy_LogicalOrListElement(yycontext *yy); /* 18 */ YY_RULE(int) yy_LogicalOrClose(yycontext *yy); /* 17 */ YY_RULE(int) yy_LogicalOrList(yycontext *yy); /* 16 */ YY_RULE(int) yy_LogicalOrOpen(yycontext *yy); /* 15 */ YY_RULE(int) yy_LogicalOr(yycontext *yy); /* 14 */ YY_RULE(int) yy_Mode(yycontext *yy); /* 13 */ YY_RULE(int) yy_ClosingBracket(yycontext *yy); /* 12 */ YY_RULE(int) yy_OpenBracket(yycontext *yy); /* 11 */ YY_RULE(int) yy_IncludeLine(yycontext *yy); /* 10 */ YY_RULE(int) yy_SpaceLine(yycontext *yy); /* 9 */ YY_RULE(int) yy_CommentLine(yycontext *yy); /* 8 */ YY_RULE(int) yy_ModeLine(yycontext *yy); /* 7 */ YY_RULE(int) yy_TagLine(yycontext *yy); /* 6 */ YY_RULE(int) yy_EndOfLine(yycontext *yy); /* 5 */ YY_RULE(int) yy_LineType(yycontext *yy); /* 4 */ YY_RULE(int) yy_EndOfFile(yycontext *yy); /* 3 */ YY_RULE(int) yy_Line(yycontext *yy); /* 2 */ YY_RULE(int) yy_start(yycontext *yy); /* 1 */ YY_ACTION(void) yy_1_EndOfLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_EndOfLine\n")); { #line 0 incrlineno();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_RegEx(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_RegEx\n")); { #line 0 regex_push ( yytext ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Only(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Only\n")); { #line 0 ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_6_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_6_ValueReference\n")); { #line 0 parser_state.any_reference = only_ref; ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_5_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_ValueReference\n")); { #line 0 parser_state.any_reference = ntupel_ref; ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_ValueReference\n")); { #line 0 parser_state.any_reference = range_ref; ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_ValueReference\n")); { #line 0 parser_state.any_reference = regex_ref; ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_ValueReference\n")); { #line 0 parser_state.any_reference = only_ref; i_push(atol(yytext) );; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_ValueReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_ValueReference\n")); { #line 0 parser_state.any_reference = any_ref; ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_NTupel(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_NTupel\n")); { #line 0 int v=parser_state.valuelist; i_push(v); reset_valuelist(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Value(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Value\n")); { #line 0 incr_values(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Number(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Number\n")); { #line 0 i_push(atol(yytext) );; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Number(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Number\n")); { #line 0 i_push(2<__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Number\n")); { #line 0 i_push(strtol(yytext, NULL, 0) ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_8_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_8_Content\n")); { #line 0 v_push( iccprofile ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_7_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_7_Content\n")); { #line 0 v_push( datetime ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_6_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_6_Content\n")); { #line 0 v_push( printable_ascii ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_5_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_Content\n")); { #line 0 v_push( regex ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Content\n")); { #line 0 v_push( ntupel ); reset_valuelist() ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Content\n")); { #line 0 v_push( only ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Content\n")); { #line 0 v_push( range); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Content(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Content\n")); { #line 0 v_push( any ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Requirements(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Requirements\n")); { #line 0 set_optional(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Requirements(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Requirements\n")); { #line 0 set_optdepends(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Requirements(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Requirements\n")); { #line 0 set_ifdepends(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Requirements(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Requirements\n")); { #line 0 set_mandatory(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_TagReference(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_TagReference\n")); { #line 0 int tag = i_pop(); if (tag < 254) set_parse_error("wrong tagreference (should be >253)", yytext); else if (tag > 65535) set_parse_error("wrong tagreference (should be <65536)", yytext); else settagref( tag ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Tag(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Tag\n")); { #line 0 int tag = i_pop(); /* rule_tagorder_in_dsl( tag ); */ if (tag < 254) set_parse_error("wrong tag (should be >253)", yytext); else if (tag > 65535) set_parse_error("wrong tag (should be <65536)", yytext); else settag( tag ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_TagLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_TagLine\n")); { #line 0 set_rule_logical_close(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_TagLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_TagLine\n")); { #line 0 rule_addtag_config(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_Mode(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_Mode\n")); { #line 0 i_push(mode_enable_ifd_checks); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_Mode(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_Mode\n")); { #line 0 i_push(mode_enable_offset_checks); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_Mode(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_Mode\n")); { #line 0 i_push(mode_enable_type_checks); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_Mode(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_Mode\n")); { #line 0 i_push(mode_baseline ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_7_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_7_LogicalOrListElement\n")); { #line 0 v_push( printable_ascii ); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_6_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_6_LogicalOrListElement\n")); { #line 0 v_push( regex ); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_5_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_5_LogicalOrListElement\n")); { #line 0 v_push( ntupel); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_4_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_4_LogicalOrListElement\n")); { #line 0 v_push( only ); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_3_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_3_LogicalOrListElement\n")); { #line 0 v_push( only ); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_2_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_2_LogicalOrListElement\n")); { #line 0 v_push( range); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_LogicalOrListElement(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_LogicalOrListElement\n")); { #line 0 v_push( any ); incr_logical_elements();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_LogicalOrClose(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_LogicalOrClose\n")); { #line 0 ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_LogicalOrOpen(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_LogicalOrOpen\n")); { #line 0 set_rule_logical_open();; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_ModeLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_ModeLine\n")); { #line 0 int i = i_pop(); set_mode( i ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_IncludeLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_IncludeLine\n")); { #line 0 set_include ( yytext ); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_CommentLine(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_CommentLine\n")); { #line 0 commentline(); ; } #undef yythunkpos #undef yypos #undef yy } YY_ACTION(void) yy_1_LineType(yycontext *yy, char *yytext, int yyleng) { #define __ yy->__ #define yypos yy->__pos #define yythunkpos yy->__thunkpos yyprintf((stderr, "do yy_1_LineType\n")); { #line 0 fprintf(stderr, "REST: '%s'\n", yytext); ; } #undef yythunkpos #undef yypos #undef yy } YY_RULE(int) yy_EscapedPCRE(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "EscapedPCRE")); { int yypos2= yy->__pos, yythunkpos2= yy->__thunkpos; if (!yymatchChar(yy, '\\')) goto l3; if (!yymatchChar(yy, '\\')) goto l3; goto l2; l3:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchChar(yy, '\\')) goto l1; if (!yymatchChar(yy, '"')) goto l1; } l2:; yyprintf((stderr, " ok %s @ %s\n", "EscapedPCRE", yy->__buf+yy->__pos)); return 1; l1:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "EscapedPCRE", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_PCRE(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "PCRE")); { int yypos5= yy->__pos, yythunkpos5= yy->__thunkpos; if (!yy_EscapedPCRE(yy)) goto l6; goto l5; l6:; yy->__pos= yypos5; yy->__thunkpos= yythunkpos5; if (!yymatchClass(yy, (unsigned char *)"\377\377\377\377\373\377\377\377\377\377\377\357\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377")) goto l4; } l5:; yyprintf((stderr, " ok %s @ %s\n", "PCRE", yy->__buf+yy->__pos)); return 1; l4:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "PCRE", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Value(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Value")); if (!yy_Number(yy)) goto l7; yyDo(yy, yy_1_Value, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "Value", yy->__buf+yy->__pos)); return 1; l7:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Value", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_ValueList(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "ValueList")); if (!yy_Value(yy)) goto l8; l9:; { int yypos10= yy->__pos, yythunkpos10= yy->__thunkpos; if (!yy_Colon(yy)) goto l10; if (!yy_Value(yy)) goto l10; goto l9; l10:; yy->__pos= yypos10; yy->__thunkpos= yythunkpos10; } yyprintf((stderr, " ok %s @ %s\n", "ValueList", yy->__buf+yy->__pos)); return 1; l8:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "ValueList", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Digit(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Digit")); if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l11; yyprintf((stderr, " ok %s @ %s\n", "Digit", yy->__buf+yy->__pos)); return 1; l11:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Digit", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Iccprofile(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Iccprofile")); if (!yymatchString(yy, "iccprofile")) goto l12; yyprintf((stderr, " ok %s @ %s\n", "Iccprofile", yy->__buf+yy->__pos)); return 1; l12:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Iccprofile", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Datetime(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Datetime")); if (!yymatchString(yy, "datetime")) goto l13; yyprintf((stderr, " ok %s @ %s\n", "Datetime", yy->__buf+yy->__pos)); return 1; l13:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Datetime", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_ValueReference(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "ValueReference")); { int yypos15= yy->__pos, yythunkpos15= yy->__thunkpos; if (!yy_Any(yy)) goto l16; yyDo(yy, yy_1_ValueReference, yy->__begin, yy->__end); goto l15; l16:; yy->__pos= yypos15; yy->__thunkpos= yythunkpos15; if (!yy_Number(yy)) goto l17; yyDo(yy, yy_2_ValueReference, yy->__begin, yy->__end); goto l15; l17:; yy->__pos= yypos15; yy->__thunkpos= yythunkpos15; if (!yy_RegEx(yy)) goto l18; yyDo(yy, yy_3_ValueReference, yy->__begin, yy->__end); goto l15; l18:; yy->__pos= yypos15; yy->__thunkpos= yythunkpos15; if (!yy_Range(yy)) goto l19; yyDo(yy, yy_4_ValueReference, yy->__begin, yy->__end); goto l15; l19:; yy->__pos= yypos15; yy->__thunkpos= yythunkpos15; if (!yy_NTupel(yy)) goto l20; yyDo(yy, yy_5_ValueReference, yy->__begin, yy->__end); goto l15; l20:; yy->__pos= yypos15; yy->__thunkpos= yythunkpos15; if (!yy_Only(yy)) goto l14; yyDo(yy, yy_6_ValueReference, yy->__begin, yy->__end); } l15:; yyprintf((stderr, " ok %s @ %s\n", "ValueReference", yy->__buf+yy->__pos)); return 1; l14:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "ValueReference", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Dot(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Dot")); if (!yymatchChar(yy, '.')) goto l21; l22:; { int yypos23= yy->__pos, yythunkpos23= yy->__thunkpos; if (!yy_Space(yy)) goto l23; goto l22; l23:; yy->__pos= yypos23; yy->__thunkpos= yythunkpos23; } yyprintf((stderr, " ok %s @ %s\n", "Dot", yy->__buf+yy->__pos)); return 1; l21:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Dot", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_OptDepends(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "OptDepends")); if (!yymatchString(yy, "optdepends")) goto l24; if (!yy_OpenBracket(yy)) goto l24; if (!yy_TagReference(yy)) goto l24; if (!yy_Dot(yy)) goto l24; if (!yy_ValueReference(yy)) goto l24; if (!yy_ClosingBracket(yy)) goto l24; yyprintf((stderr, " ok %s @ %s\n", "OptDepends", yy->__buf+yy->__pos)); return 1; l24:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "OptDepends", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_IfDepends(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "IfDepends")); if (!yymatchString(yy, "depends")) goto l25; if (!yy_OpenBracket(yy)) goto l25; if (!yy_TagReference(yy)) goto l25; if (!yy_Dot(yy)) goto l25; if (!yy_ValueReference(yy)) goto l25; if (!yy_ClosingBracket(yy)) goto l25; yyprintf((stderr, " ok %s @ %s\n", "IfDepends", yy->__buf+yy->__pos)); return 1; l25:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "IfDepends", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Space(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Space")); { int yypos27= yy->__pos, yythunkpos27= yy->__thunkpos; if (!yymatchChar(yy, ' ')) goto l28; goto l27; l28:; yy->__pos= yypos27; yy->__thunkpos= yythunkpos27; if (!yymatchChar(yy, '\t')) goto l26; } l27:; yyprintf((stderr, " ok %s @ %s\n", "Space", yy->__buf+yy->__pos)); return 1; l26:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Space", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_TagReference(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "TagReference")); yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l29; #undef yytext #undef yyleng } if (!yy_Number(yy)) goto l29; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l29; #undef yytext #undef yyleng } yyDo(yy, yy_1_TagReference, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "TagReference", yy->__buf+yy->__pos)); return 1; l29:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "TagReference", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Content(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Content")); { int yypos31= yy->__pos, yythunkpos31= yy->__thunkpos; if (!yy_Any(yy)) goto l32; yyDo(yy, yy_1_Content, yy->__begin, yy->__end); goto l31; l32:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_Range(yy)) goto l33; yyDo(yy, yy_2_Content, yy->__begin, yy->__end); goto l31; l33:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_Only(yy)) goto l34; yyDo(yy, yy_3_Content, yy->__begin, yy->__end); goto l31; l34:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_NTupel(yy)) goto l35; yyDo(yy, yy_4_Content, yy->__begin, yy->__end); goto l31; l35:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_RegEx(yy)) goto l36; yyDo(yy, yy_5_Content, yy->__begin, yy->__end); goto l31; l36:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_PrintableAscii(yy)) goto l37; yyDo(yy, yy_6_Content, yy->__begin, yy->__end); goto l31; l37:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_Datetime(yy)) goto l38; yyDo(yy, yy_7_Content, yy->__begin, yy->__end); goto l31; l38:; yy->__pos= yypos31; yy->__thunkpos= yythunkpos31; if (!yy_Iccprofile(yy)) goto l30; yyDo(yy, yy_8_Content, yy->__begin, yy->__end); } l31:; yyprintf((stderr, " ok %s @ %s\n", "Content", yy->__buf+yy->__pos)); return 1; l30:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Content", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Requirements(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Requirements")); { int yypos40= yy->__pos, yythunkpos40= yy->__thunkpos; if (!yymatchString(yy, "mandatory")) goto l41; yyDo(yy, yy_1_Requirements, yy->__begin, yy->__end); goto l40; l41:; yy->__pos= yypos40; yy->__thunkpos= yythunkpos40; if (!yy_IfDepends(yy)) goto l42; yyDo(yy, yy_2_Requirements, yy->__begin, yy->__end); goto l40; l42:; yy->__pos= yypos40; yy->__thunkpos= yythunkpos40; if (!yy_OptDepends(yy)) goto l43; yyDo(yy, yy_3_Requirements, yy->__begin, yy->__end); goto l40; l43:; yy->__pos= yypos40; yy->__thunkpos= yythunkpos40; if (!yymatchString(yy, "optional")) goto l39; yyDo(yy, yy_4_Requirements, yy->__begin, yy->__end); } l40:; yyprintf((stderr, " ok %s @ %s\n", "Requirements", yy->__buf+yy->__pos)); return 1; l39:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Requirements", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Semicolon(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Semicolon")); if (!yymatchChar(yy, ';')) goto l44; l45:; { int yypos46= yy->__pos, yythunkpos46= yy->__thunkpos; if (!yy_Space(yy)) goto l46; goto l45; l46:; yy->__pos= yypos46; yy->__thunkpos= yythunkpos46; } yyprintf((stderr, " ok %s @ %s\n", "Semicolon", yy->__buf+yy->__pos)); return 1; l44:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Semicolon", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Tag(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Tag")); yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l47; #undef yytext #undef yyleng } if (!yy_Number(yy)) goto l47; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l47; #undef yytext #undef yyleng } yyDo(yy, yy_1_Tag, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "Tag", yy->__buf+yy->__pos)); return 1; l47:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Tag", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Colon(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Colon")); if (!yymatchChar(yy, ',')) goto l48; l49:; { int yypos50= yy->__pos, yythunkpos50= yy->__thunkpos; if (!yy_Space(yy)) goto l50; goto l49; l50:; yy->__pos= yypos50; yy->__thunkpos= yythunkpos50; } yyprintf((stderr, " ok %s @ %s\n", "Colon", yy->__buf+yy->__pos)); return 1; l48:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Colon", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_PrintableAscii(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "PrintableAscii")); if (!yymatchString(yy, "printascii")) goto l51; yyprintf((stderr, " ok %s @ %s\n", "PrintableAscii", yy->__buf+yy->__pos)); return 1; l51:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "PrintableAscii", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_RegEx(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "RegEx")); if (!yymatchString(yy, "regex")) goto l52; if (!yy_OpenBracket(yy)) goto l52; if (!yymatchChar(yy, '"')) goto l52; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l52; #undef yytext #undef yyleng } l53:; { int yypos54= yy->__pos, yythunkpos54= yy->__thunkpos; if (!yy_PCRE(yy)) goto l54; goto l53; l54:; yy->__pos= yypos54; yy->__thunkpos= yythunkpos54; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l52; #undef yytext #undef yyleng } if (!yymatchChar(yy, '"')) goto l52; if (!yy_ClosingBracket(yy)) goto l52; yyDo(yy, yy_1_RegEx, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "RegEx", yy->__buf+yy->__pos)); return 1; l52:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "RegEx", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_NTupel(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "NTupel")); if (!yymatchString(yy, "ntupel")) goto l55; if (!yy_OpenBracket(yy)) goto l55; if (!yy_ValueList(yy)) goto l55; if (!yy_ClosingBracket(yy)) goto l55; yyDo(yy, yy_1_NTupel, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "NTupel", yy->__buf+yy->__pos)); return 1; l55:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "NTupel", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Number(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Number")); { int yypos57= yy->__pos, yythunkpos57= yy->__thunkpos; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l58; #undef yytext #undef yyleng } if (!yymatchString(yy, "0x")) goto l58; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l58; l59:; { int yypos60= yy->__pos, yythunkpos60= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\176\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l60; goto l59; l60:; yy->__pos= yypos60; yy->__thunkpos= yythunkpos60; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l58; #undef yytext #undef yyleng } yyDo(yy, yy_1_Number, yy->__begin, yy->__end); goto l57; l58:; yy->__pos= yypos57; yy->__thunkpos= yythunkpos57; if (!yymatchString(yy, "2^")) goto l61; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l61; #undef yytext #undef yyleng } if (!yy_Digit(yy)) goto l61; l62:; { int yypos63= yy->__pos, yythunkpos63= yy->__thunkpos; if (!yy_Digit(yy)) goto l63; goto l62; l63:; yy->__pos= yypos63; yy->__thunkpos= yythunkpos63; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l61; #undef yytext #undef yyleng } yyDo(yy, yy_2_Number, yy->__begin, yy->__end); goto l57; l61:; yy->__pos= yypos57; yy->__thunkpos= yythunkpos57; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l56; #undef yytext #undef yyleng } if (!yy_Digit(yy)) goto l56; l64:; { int yypos65= yy->__pos, yythunkpos65= yy->__thunkpos; if (!yy_Digit(yy)) goto l65; goto l64; l65:; yy->__pos= yypos65; yy->__thunkpos= yythunkpos65; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l56; #undef yytext #undef yyleng } yyDo(yy, yy_3_Number, yy->__begin, yy->__end); } l57:; yyprintf((stderr, " ok %s @ %s\n", "Number", yy->__buf+yy->__pos)); return 1; l56:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Number", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Only(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Only")); if (!yymatchString(yy, "only")) goto l66; if (!yy_OpenBracket(yy)) goto l66; if (!yy_Number(yy)) goto l66; if (!yy_ClosingBracket(yy)) goto l66; yyDo(yy, yy_1_Only, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "Only", yy->__buf+yy->__pos)); return 1; l66:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Only", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Range(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Range")); if (!yymatchString(yy, "range")) goto l67; if (!yy_OpenBracket(yy)) goto l67; if (!yy_Number(yy)) goto l67; if (!yy_Colon(yy)) goto l67; if (!yy_Number(yy)) goto l67; if (!yy_ClosingBracket(yy)) goto l67; yyprintf((stderr, " ok %s @ %s\n", "Range", yy->__buf+yy->__pos)); return 1; l67:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Range", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Any(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Any")); if (!yymatchString(yy, "any")) goto l68; yyprintf((stderr, " ok %s @ %s\n", "Any", yy->__buf+yy->__pos)); return 1; l68:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Any", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LogicalOrListElement(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LogicalOrListElement")); { int yypos70= yy->__pos, yythunkpos70= yy->__thunkpos; if (!yy_Any(yy)) goto l71; yyDo(yy, yy_1_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l71:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_Range(yy)) goto l72; yyDo(yy, yy_2_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l72:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_Only(yy)) goto l73; yyDo(yy, yy_3_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l73:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_Number(yy)) goto l74; yyDo(yy, yy_4_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l74:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_NTupel(yy)) goto l75; yyDo(yy, yy_5_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l75:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_RegEx(yy)) goto l76; yyDo(yy, yy_6_LogicalOrListElement, yy->__begin, yy->__end); goto l70; l76:; yy->__pos= yypos70; yy->__thunkpos= yythunkpos70; if (!yy_PrintableAscii(yy)) goto l69; yyDo(yy, yy_7_LogicalOrListElement, yy->__begin, yy->__end); } l70:; yyprintf((stderr, " ok %s @ %s\n", "LogicalOrListElement", yy->__buf+yy->__pos)); return 1; l69:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LogicalOrListElement", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LogicalOrClose(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LogicalOrClose")); if (!yy_ClosingBracket(yy)) goto l77; yyDo(yy, yy_1_LogicalOrClose, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "LogicalOrClose", yy->__buf+yy->__pos)); return 1; l77:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LogicalOrClose", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LogicalOrList(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LogicalOrList")); if (!yy_LogicalOrListElement(yy)) goto l78; l79:; { int yypos80= yy->__pos, yythunkpos80= yy->__thunkpos; if (!yy_Colon(yy)) goto l80; if (!yy_LogicalOrListElement(yy)) goto l80; goto l79; l80:; yy->__pos= yypos80; yy->__thunkpos= yythunkpos80; } yyprintf((stderr, " ok %s @ %s\n", "LogicalOrList", yy->__buf+yy->__pos)); return 1; l78:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LogicalOrList", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LogicalOrOpen(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LogicalOrOpen")); if (!yy_OpenBracket(yy)) goto l81; yyDo(yy, yy_1_LogicalOrOpen, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "LogicalOrOpen", yy->__buf+yy->__pos)); return 1; l81:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LogicalOrOpen", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LogicalOr(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LogicalOr")); if (!yymatchString(yy, "logical_or")) goto l82; if (!yy_LogicalOrOpen(yy)) goto l82; if (!yy_LogicalOrList(yy)) goto l82; if (!yy_LogicalOrClose(yy)) goto l82; yyprintf((stderr, " ok %s @ %s\n", "LogicalOr", yy->__buf+yy->__pos)); return 1; l82:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LogicalOr", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Mode(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Mode")); { int yypos84= yy->__pos, yythunkpos84= yy->__thunkpos; if (!yymatchString(yy, "baseline")) goto l85; yyDo(yy, yy_1_Mode, yy->__begin, yy->__end); goto l84; l85:; yy->__pos= yypos84; yy->__thunkpos= yythunkpos84; if (!yymatchString(yy, "enable_type_checks")) goto l86; yyDo(yy, yy_2_Mode, yy->__begin, yy->__end); goto l84; l86:; yy->__pos= yypos84; yy->__thunkpos= yythunkpos84; if (!yymatchString(yy, "enable_offset_checks")) goto l87; yyDo(yy, yy_3_Mode, yy->__begin, yy->__end); goto l84; l87:; yy->__pos= yypos84; yy->__thunkpos= yythunkpos84; if (!yymatchString(yy, "enable_ifd_checks")) goto l88; yyDo(yy, yy_4_Mode, yy->__begin, yy->__end); goto l84; l88:; yy->__pos= yypos84; yy->__thunkpos= yythunkpos84; if (!yymatchString(yy, "enhanced")) goto l83; } l84:; yyprintf((stderr, " ok %s @ %s\n", "Mode", yy->__buf+yy->__pos)); return 1; l83:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Mode", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_ClosingBracket(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "ClosingBracket")); if (!yymatchChar(yy, ')')) goto l89; yyprintf((stderr, " ok %s @ %s\n", "ClosingBracket", yy->__buf+yy->__pos)); return 1; l89:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "ClosingBracket", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_OpenBracket(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "OpenBracket")); if (!yymatchChar(yy, '(')) goto l90; yyprintf((stderr, " ok %s @ %s\n", "OpenBracket", yy->__buf+yy->__pos)); return 1; l90:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "OpenBracket", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_IncludeLine(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "IncludeLine")); if (!yymatchString(yy, "include")) goto l91; if (!yy_OpenBracket(yy)) goto l91; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l91; #undef yytext #undef yyleng } if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\340\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l91; l92:; { int yypos93= yy->__pos, yythunkpos93= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\340\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l93; goto l92; l93:; yy->__pos= yypos93; yy->__thunkpos= yythunkpos93; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l91; #undef yytext #undef yyleng } if (!yy_ClosingBracket(yy)) goto l91; yyDo(yy, yy_1_IncludeLine, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "IncludeLine", yy->__buf+yy->__pos)); return 1; l91:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "IncludeLine", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_SpaceLine(yycontext *yy) { yyprintf((stderr, "%s\n", "SpaceLine")); l95:; { int yypos96= yy->__pos, yythunkpos96= yy->__thunkpos; if (!yy_Space(yy)) goto l96; goto l95; l96:; yy->__pos= yypos96; yy->__thunkpos= yythunkpos96; } yyprintf((stderr, " ok %s @ %s\n", "SpaceLine", yy->__buf+yy->__pos)); return 1; } YY_RULE(int) yy_CommentLine(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "CommentLine")); if (!yymatchChar(yy, '#')) goto l97; l98:; { int yypos99= yy->__pos, yythunkpos99= yy->__thunkpos; { int yypos100= yy->__pos, yythunkpos100= yy->__thunkpos; if (!yy_EndOfLine(yy)) goto l100; goto l99; l100:; yy->__pos= yypos100; yy->__thunkpos= yythunkpos100; } if (!yymatchDot(yy)) goto l99; goto l98; l99:; yy->__pos= yypos99; yy->__thunkpos= yythunkpos99; } yyDo(yy, yy_1_CommentLine, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "CommentLine", yy->__buf+yy->__pos)); return 1; l97:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "CommentLine", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_ModeLine(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "ModeLine")); if (!yymatchString(yy, "mode")) goto l101; if (!yy_OpenBracket(yy)) goto l101; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l101; #undef yytext #undef yyleng } if (!yy_Mode(yy)) goto l101; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l101; #undef yytext #undef yyleng } if (!yy_ClosingBracket(yy)) goto l101; yyDo(yy, yy_1_ModeLine, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "ModeLine", yy->__buf+yy->__pos)); return 1; l101:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "ModeLine", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_TagLine(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "TagLine")); { int yypos103= yy->__pos, yythunkpos103= yy->__thunkpos; if (!yy_Tag(yy)) goto l104; if (!yy_Semicolon(yy)) goto l104; if (!yy_Requirements(yy)) goto l104; if (!yy_Semicolon(yy)) goto l104; if (!yy_Content(yy)) goto l104; yyDo(yy, yy_1_TagLine, yy->__begin, yy->__end); goto l103; l104:; yy->__pos= yypos103; yy->__thunkpos= yythunkpos103; if (!yy_Tag(yy)) goto l102; if (!yy_Semicolon(yy)) goto l102; if (!yy_Requirements(yy)) goto l102; if (!yy_Semicolon(yy)) goto l102; if (!yy_LogicalOr(yy)) goto l102; yyDo(yy, yy_2_TagLine, yy->__begin, yy->__end); } l103:; yyprintf((stderr, " ok %s @ %s\n", "TagLine", yy->__buf+yy->__pos)); return 1; l102:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "TagLine", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_EndOfLine(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "EndOfLine")); if (!yymatchClass(yy, (unsigned char *)"\000\044\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l105; yyDo(yy, yy_1_EndOfLine, yy->__begin, yy->__end); yyprintf((stderr, " ok %s @ %s\n", "EndOfLine", yy->__buf+yy->__pos)); return 1; l105:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "EndOfLine", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_LineType(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "LineType")); { int yypos107= yy->__pos, yythunkpos107= yy->__thunkpos; if (!yy_TagLine(yy)) goto l108; goto l107; l108:; yy->__pos= yypos107; yy->__thunkpos= yythunkpos107; if (!yy_ModeLine(yy)) goto l109; goto l107; l109:; yy->__pos= yypos107; yy->__thunkpos= yythunkpos107; if (!yy_CommentLine(yy)) goto l110; goto l107; l110:; yy->__pos= yypos107; yy->__thunkpos= yythunkpos107; if (!yy_SpaceLine(yy)) goto l111; goto l107; l111:; yy->__pos= yypos107; yy->__thunkpos= yythunkpos107; if (!yy_IncludeLine(yy)) goto l112; goto l107; l112:; yy->__pos= yypos107; yy->__thunkpos= yythunkpos107; yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_BEGIN)) goto l106; #undef yytext #undef yyleng } { int yypos115= yy->__pos, yythunkpos115= yy->__thunkpos; if (!yy_EndOfLine(yy)) goto l115; goto l106; l115:; yy->__pos= yypos115; yy->__thunkpos= yythunkpos115; } if (!yymatchDot(yy)) goto l106; l113:; { int yypos114= yy->__pos, yythunkpos114= yy->__thunkpos; { int yypos116= yy->__pos, yythunkpos116= yy->__thunkpos; if (!yy_EndOfLine(yy)) goto l116; goto l114; l116:; yy->__pos= yypos116; yy->__thunkpos= yythunkpos116; } if (!yymatchDot(yy)) goto l114; goto l113; l114:; yy->__pos= yypos114; yy->__thunkpos= yythunkpos114; } yyText(yy, yy->__begin, yy->__end); { #define yytext yy->__text #define yyleng yy->__textlen if (!(YY_END)) goto l106; #undef yytext #undef yyleng } yyDo(yy, yy_1_LineType, yy->__begin, yy->__end); } l107:; yyprintf((stderr, " ok %s @ %s\n", "LineType", yy->__buf+yy->__pos)); return 1; l106:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "LineType", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_EndOfFile(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "EndOfFile")); { int yypos118= yy->__pos, yythunkpos118= yy->__thunkpos; if (!yymatchDot(yy)) goto l118; goto l117; l118:; yy->__pos= yypos118; yy->__thunkpos= yythunkpos118; } yyprintf((stderr, " ok %s @ %s\n", "EndOfFile", yy->__buf+yy->__pos)); return 1; l117:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "EndOfFile", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_Line(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "Line")); if (!yy_LineType(yy)) goto l119; if (!yy_EndOfLine(yy)) goto l119; yyprintf((stderr, " ok %s @ %s\n", "Line", yy->__buf+yy->__pos)); return 1; l119:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "Line", yy->__buf+yy->__pos)); return 0; } YY_RULE(int) yy_start(yycontext *yy) { int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyprintf((stderr, "%s\n", "start")); if (!yy_Line(yy)) goto l120; l121:; { int yypos122= yy->__pos, yythunkpos122= yy->__thunkpos; if (!yy_Line(yy)) goto l122; goto l121; l122:; yy->__pos= yypos122; yy->__thunkpos= yythunkpos122; } if (!yy_EndOfFile(yy)) goto l120; yyprintf((stderr, " ok %s @ %s\n", "start", yy->__buf+yy->__pos)); return 1; l120:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; yyprintf((stderr, " fail %s @ %s\n", "start", yy->__buf+yy->__pos)); return 0; } #ifndef YY_PART typedef int (*yyrule)(yycontext *yy); YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart) { int yyok; if (!yyctx->__buflen) { yyctx->__buflen= YY_BUFFER_SIZE; yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen); yyctx->__textlen= YY_BUFFER_SIZE; yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen); yyctx->__thunkslen= YY_STACK_SIZE; yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen); yyctx->__valslen= YY_STACK_SIZE; yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen); yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0; } yyctx->__begin= yyctx->__end= yyctx->__pos; yyctx->__thunkpos= 0; yyctx->__val= yyctx->__vals; yyok= yystart(yyctx); if (yyok) yyDone(yyctx); yyCommit(yyctx); return yyok; } YY_PARSE(int) YYPARSE(YY_CTX_PARAM) { return YYPARSEFROM(YY_CTX_ARG_ yy_start); } YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx) { if (yyctx->__buflen) { yyctx->__buflen= 0; YY_FREE(yyctx, yyctx->__buf); YY_FREE(yyctx, yyctx->__text); YY_FREE(yyctx, yyctx->__thunks); YY_FREE(yyctx, yyctx->__vals); } return yyctx; } #endif checkit_tiff-0.4.2/src/parser/config_dsl.grammar.peg000066400000000000000000000160551327425157300224730ustar00rootroot00000000000000# rule based checks if given TIFF is a specific baseline TIFF # # author: Andreas Romeyke, 2015-2017 # licensed under conditions of libtiff # (see http://libtiff.maptools.org/misc.html) # start <- ( Line )+ EndOfFile Line <- LineType EndOfLine LineType <- TagLine / ModeLine / CommentLine / SpaceLine / IncludeLine / < ( !EndOfLine .)+ > {fprintf(stderr, "REST: '%s'\n", yytext); } CommentLine <- '#' ( !EndOfLine .)* { commentline(); } IncludeLine <- 'include' OpenBracket < ( [A-Za-z0-9_./\-]+ ) > ClosingBracket { set_include ( yytext ); } ModeLine <- 'mode' OpenBracket < Mode > ClosingBracket { int i = i_pop(); set_mode( i ); } LogicalOr <- 'logical_or' LogicalOrOpen LogicalOrList LogicalOrClose LogicalOrOpen <- OpenBracket { set_rule_logical_open();} LogicalOrClose <- ClosingBracket { } LogicalOrListElement <- Any { v_push( any ); incr_logical_elements();} / Range { v_push( range); incr_logical_elements();} / Only { v_push( only ); incr_logical_elements();} / Number { v_push( only ); incr_logical_elements();} / NTupel { v_push( ntupel); incr_logical_elements();} / RegEx { v_push( regex ); incr_logical_elements();} / PrintableAscii { v_push( printable_ascii ); incr_logical_elements();} LogicalOrList <- LogicalOrListElement (Colon LogicalOrListElement)* Mode <- 'baseline' { i_push(mode_baseline ); } / 'enable_type_checks' { i_push(mode_enable_type_checks); } / 'enable_offset_checks' { i_push(mode_enable_offset_checks); } / 'enable_ifd_checks' { i_push(mode_enable_ifd_checks); } / 'enhanced' #/* TODO: later if all types of TIFF are supported */ TagLine <- Tag Semicolon Requirements Semicolon Content { rule_addtag_config(); } / Tag Semicolon Requirements Semicolon LogicalOr { set_rule_logical_close(); } Tag <- < Number > { int tag = i_pop(); /* rule_tagorder_in_dsl( tag ); */ if (tag < 254) set_parse_error("wrong tag (should be >253)", yytext); else if (tag > 65535) set_parse_error("wrong tag (should be <65536)", yytext); else settag( tag ); } TagReference <- < Number > { int tag = i_pop(); if (tag < 254) set_parse_error("wrong tagreference (should be >253)", yytext); else if (tag > 65535) set_parse_error("wrong tagreference (should be <65536)", yytext); else settagref( tag ); } Semicolon <- ';' ( Space )* Requirements <- 'mandatory' { set_mandatory(); } / IfDepends { set_ifdepends(); } / OptDepends { set_optdepends(); } / 'optional' { set_optional(); } IfDepends <- 'depends' OpenBracket TagReference Dot ValueReference ClosingBracket OptDepends <- 'optdepends' OpenBracket TagReference Dot ValueReference ClosingBracket Content <- Any { v_push( any ); } / Range { v_push( range); } / Only { v_push( only ); } / NTupel { v_push( ntupel ); reset_valuelist() } / RegEx { v_push( regex ); } / PrintableAscii { v_push( printable_ascii ); } / Datetime { v_push( datetime ); } / Iccprofile { v_push( iccprofile ); } # / SBit { v_push( sbit ); } Range <- 'range' OpenBracket Number Colon Number ClosingBracket Number <- < '0x' ( [0-9a-f]+ ) > { i_push(strtol(yytext, NULL, 0) ); } / '2^' < ( Digit )+ > { i_push(2< { i_push(atol(yytext) );} Colon <- ',' (Space )* Dot <- '.' (Space )* OpenBracket <- '(' ClosingBracket <- ')' ValueList <- Value (Colon Value)* Value <- Number { incr_values(); } NTupel <- 'ntupel' OpenBracket ValueList ClosingBracket {int v=parser_state.valuelist; i_push(v); reset_valuelist(); } ValueReference <- Any { parser_state.any_reference = any_ref; } / Number { parser_state.any_reference = only_ref; i_push(atol(yytext) );} / RegEx { parser_state.any_reference = regex_ref; } / Range { parser_state.any_reference = range_ref; } / NTupel { parser_state.any_reference = ntupel_ref; } / Only { parser_state.any_reference = only_ref; } Only <- 'only' OpenBracket Number ClosingBracket { } #SBit <- 'sbit' OpenBracket < Digit > ClosingBracket{ i_push(atol(yytext) ); } # / 'sbit' OpenBracket Digit { set_parse_error("'sbit' expects a closing bracket", yytext); } # / 'sbit' OpenBracket { set_parse_error("'sbit' expects a digit", yytext); } # / 'sbit' { set_parse_error("'sbit' expects an open bracket", yytext); } RegEx <- 'regex' OpenBracket '"' < ( PCRE )* > '"' ClosingBracket { regex_push ( yytext ); } Datetime <- 'datetime' Iccprofile <- 'iccprofile' PrintableAscii <- 'printascii' SpaceLine <- ( Space )* Space <- ' ' / '\t' Any <- 'any' Digit <- [0-9] EndOfLine <- [\r\n] {incrlineno();} EndOfFile <- !. PCRE <- EscapedPCRE / [^"\\] # FIXME: unescape char in yybuffer EscapedPCRE <- '\\' '\\' / '\\' '"' checkit_tiff-0.4.2/src/parser/config_parser.c000066400000000000000000001357201327425157300212300ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015-2017 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ /* #define YY_DEBUG */ #include #include #include #include #include "config_parser.h" #include "check.h" #include "check_helper.h" #include "msg_parser.h" #include #define YY_CTX_LOCAL /* #define RULE_DEBUG 1 #define DEBUG 1 #define EXE_DEBUG 1 #define YY_DEBUG 1 */ /* global vars */ parser_state_t parser_state; /* redefined YY_INPUT to read from stream */ #define YY_INPUT(yyctx, buf, result, max_size) \ { \ int yyc= fgetc(parser_state.stream); \ result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ yyprintf((stderr, "<%c>", yyc)); \ } /* prints a plan (list) of functions */ /* void print_plan () { printf("print plan:\n"); executionentry_t * this_exe_p = plan.start; while (NULL != this_exe_p) { printf("next action is: %s\n", this_exe_p->name); this_exe_p = this_exe_p->next; } } */ #define CHECKUNDERFLOW(SPACE_P, NAME) \ if (((SPACE_P)->NAME ## _stackp) >=MAXRESULT) {\ fprintf(stderr, "stackoverflow in " #SPACE_P "->" #NAME "_stack at lineno=%i, only %i results could be stored, increase MAXRESULT\n", parser_state.lineno, MAXRESULT);\ exit(EXIT_FAILURE);\ } // endmacro CHECKUNDERFLOW #define CHECKOVERFLOW(SPACE_P, NAME) \ if (((SPACE_P)->NAME ## _stackp) >=MAXRESULT) {\ fprintf(stderr, "stackoverflow in " #SPACE_P "->" #NAME "_stack at lineno=%i, only %i results could be stored, increase MAXRESULT\n", parser_state.lineno, MAXRESULT);\ exit(EXIT_FAILURE);\ } // endmacro CHECKOVERFLOW #define PUSH(SPACE_P, NAME, RES) \ (SPACE_P)->NAME ## _stack[((SPACE_P)->NAME ## _stackp)++]=RES;\ CHECKOVERFLOW(SPACE_P, NAME) //endmacro PUSH #define POP(SPACE_P, NAME, RES) \ CHECKUNDERFLOW(SPACE_P, NAME) \ (RES)=(SPACE_P)->NAME ## _stack[--((SPACE_P)->NAME ## _stackp)]; //endmacro POP #define PRINT(SPACE_P, TYPESIG, NAME) \ CHECKOVERFLOW(SPACE_P, NAME) \ CHECKUNDERFLOW(SPACE_P, NAME) \ for (int j=0; j< (SPACE_P)->NAME ## _stackp; j++)\ printf(" " #SPACE_P "->" #NAME "-stack value[ %i ] --> " #TYPESIG "\n", j, (SPACE_P)->NAME ## _stack[j]);\ //endmacro PRINT #define PRINTV(SPACE_P, VSTRINGARRAY, NAME) \ CHECKOVERFLOW(SPACE_P, NAME) \ CHECKUNDERFLOW(SPACE_P, NAME) \ for (int j=0; j< (SPACE_P)->NAME ## _stackp; j++)\ printf(" " #SPACE_P "->" #NAME "-stack value[ %i ] --> %s\n", j, VSTRINGARRAY[(SPACE_P)->NAME ## _stack[j]]);\ //endmacro PRINTV void result_push(full_res_t r) { PUSH(&parser_state, result, r); } void result_printstack() { printf("=== BEGIN result_printstack\n"); for (int i = 0; i < parser_state.result_stackp; i++) { full_res_t full_result = parser_state.result_stack[i]; printf("i=%i lineno=%i tag=%hu func=%s (%i) returncode=%s (%i)\n", i, full_result.lineno, full_result.tag, get_parser_function_description(full_result.function), full_result.function, get_parser_error_description(full_result.returncode), full_result.returncode ); } printf("=== END result_printstack\n"); } void i_printstack () { PRINT(&parser_state, "%u", i); } void i_push (unsigned int i) { PUSH(&parser_state, i, i);} unsigned int i_pop () { unsigned i; POP(&parser_state, i, i); return i; } void v_printstack () { const char * vname[] = { "range", "logical_or", "any", "only", "regex", "ntupel", }; PRINTV(&parser_state, vname, val); } void v_push ( values_t v) { PUSH(&parser_state, val, v);} values_t v_pop () { values_t v; POP(&parser_state, val, v); return v; } void r_printstack () { PRINT(&parser_state, "%s", regex); } void r_push (const char * r) { PUSH(&parser_state, regex, r); } const char * r_pop () { const char * v; POP(&parser_state, regex, v); return v; } void exe_push (internal_entry_t i) { PUSH(&parser_state, exe, i);} internal_entry_t exe_pop () { internal_entry_t e; POP(&parser_state, exe, e); return e; } void exe_printstack_human_readable () { CHECKOVERFLOW(&parser_state, exe); CHECKUNDERFLOW(&parser_state, exe); printf("\n/* the rules are in stack order, the top comes first */\n\n"); for (int j=parser_state.exe_stackp-1; j>=0; j--) { printf("/* lineno=%03i */ ", parser_state.exe_stack[j].lineno ); if (parser_state.exe_stack[j].is_precondition) { printf ("PRECOND: "); } else { printf ("EXEC: "); } printf("%s tag=%i", get_parser_function_name(parser_state.exe_stack[j].function), parser_state.exe_stack[j].tag); /* print i_stack */ if ( parser_state.exe_stack[j].i_stackp >0 && parser_state.exe_stack[j].i_stackp<=MAXSTACKDEPTH) { printf (" top i stack=(%u)", parser_state.exe_stack[j].i_stack[ parser_state.exe_stack[j].i_stackp-1]); } /* print regex_stack */ if ( parser_state.exe_stack[j].regex_stackp >0 && parser_state.exe_stack[j].regex_stackp<=MAXSTACKDEPTH) { for (int i=0; i < parser_state.exe_stack[j].regex_stackp; i++) { printf(" regex_stack[%i]=%s", i, parser_state.exe_stack[j].regex_stack[i]); } } if (!parser_state.exe_stack[j].is_precondition) { printf ("\n"); } printf("\n"); } } /* help function to print exe stack */ void exe_printstack () { CHECKOVERFLOW(&parser_state, exe); CHECKUNDERFLOW(&parser_state, exe); printf("=== BEGIN exe_printstack\n"); for (int j=0; j< parser_state.exe_stackp; j++) { printf(" exe-stack value[ %i ] --> {\n\tlineno=%i\n\tis_precondition=%s (%i)\n\ttag=%hu\n\tfunction_used=%s (%i)\n", j, parser_state.exe_stack[j].lineno, (parser_state.exe_stack[j].is_precondition == true?"true":"false"), parser_state.exe_stack[j].is_precondition, parser_state.exe_stack[j].tag, get_parser_function_description(parser_state.exe_stack[j].function), parser_state.exe_stack[j].function ); /* print i_stack */ if ( parser_state.exe_stack[j].i_stackp >=0 && parser_state.exe_stack[j].i_stackp<=MAXSTACKDEPTH) { for (int i=0; i < parser_state.exe_stack[j].i_stackp; i++) { printf("\ti_stack[%i]=%u\n", i, parser_state.exe_stack[j].i_stack[i]); } } /* print regex_stack */ if ( parser_state.exe_stack[j].regex_stackp >=0 && parser_state.exe_stack[j].regex_stackp<=MAXSTACKDEPTH) { for (int i=0; i < parser_state.exe_stack[j].regex_stackp; i++) { printf("\tregex_stack[%i]=%s\n", i, parser_state.exe_stack[j].regex_stack[i]); } } printf("}\n"); } printf("=== END exe_printstack\n"); } /* reduce results */ void reduce_results() { #ifdef DEBUG printf("---------------------------------------------------------------------\n"); printf("begin REDUCE\n"); printf("---------------------------------------------------------------------\n"); #endif /* go forward and eliminate all valid rule results */ full_res_t * tmp = NULL; tmp = malloc(sizeof(full_res_t) * MAXRESULT); if (NULL == tmp) { fprintf(stderr, "Could not allocate memory\n"); exit(EXIT_FAILURE); } int tmpc=0; for (int i = 0; i < parser_state.result_stackp; i++) { full_res_t full_result = parser_state.result_stack[i]; #ifdef DEBUG printf("reduce i=%i tmpc=%i lineno=%i tag=%i func=%s returncode=%i\n", i, tmpc, full_result.lineno, full_result.tag, get_parser_function_description(full_result.function), full_result.returncode ); if (full_result.found_value != NULL) { printf("\tvalue='%s'\n", full_result.found_value);} #endif if (full_result.returncode == parser_logical_combine_open) { /* check all values until parser_logical_close found */ bool_t one_result_is_ok = false; for (int j = i+1; j < parser_state.result_stackp; j++) { full_res_t l_full_result = parser_state.result_stack[j]; if (l_full_result.returncode == parser_logical_combine_close) { if (one_result_is_ok == true) { full_result.returncode = is_valid; i=j; #ifdef DEBUG printf("\tend combine i=%i j=%i\n", i, j); #endif } break; } else { /* combine results via OR */ #ifdef DEBUG printf("\tcombine result i=%i j=%i, resultcode=%i resultmsg=%s\n", i, j, l_full_result.returncode, get_parser_error_description(l_full_result.returncode )); #endif if (l_full_result.returncode == is_valid) { one_result_is_ok = true; } } } } int has_errors=0; if (full_result.returncode != is_valid) { /* push to tmp */ tmp[tmpc++]=full_result; } else { // is valid tmp[tmpc++]=full_result; } } /* copy back */ for (int i = 0; i <= tmpc; i++) { parser_state.result_stack[i]= tmp[i]; } free(tmp); tmp=NULL; /* copy size */ parser_state.result_stackp=tmpc; #ifdef DEBUG printf("----------------------\n"); #endif } /* stack function for parser */ void exe_i_push (internal_entry_t * ep, unsigned int i) { PUSH( ep, i, i) } unsigned int exe_i_pop(internal_entry_t * ep) { unsigned int i; POP( ep, i, i); return i; } /* stack function for parser */ internal_entry_t * exe_regex_push (internal_entry_t * ep, const char * s) { #ifdef EXE_DEBUG printf("-------------------\n"); printf("\tpush REGEX='%s'\n", s); printf("-------------------\n"); #endif PUSH( ep, regex, strdup(s)) #ifdef EXE_DEBUG printf("\ton top='%s'\n", ep->regex_stack[ (ep->regex_stackp)-1 ]); #endif return ep; } const char * exe_regex_pop(internal_entry_t * ep) { const char * s; POP( ep, regex, s); #ifdef EXE_DEBUG printf("-------------------\n"); printf("\tpop REGEX='%s'\n", s); printf("-------------------\n"); printf("\ton top='%s'\n", ep->regex_stack[ (ep->regex_stackp) ]); #endif return s; } char * __ch_malloc(char * msg) { assert( msg == NULL); msg = malloc(sizeof(char) * VALUESTRLEN ); if (NULL == msg) { fprintf(stderr, "Could not allocate memory, code=%s, line=%i\n", __FILE__, __LINE__); exit(could_not_allocate_memory); } memset(msg, '\0', VALUESTRLEN); return msg; } ret_t call_exec_function(ctiff_t * ctif, ret_t * retp, internal_entry_t * exep) { ret_t ret = *retp; internal_entry_t exe = *exep; char * expected_value=NULL; switch (exe.function) { case fc_true: { ret.returncode=is_valid; break;} case fc_false: { ret.returncode=is_error; break; } case fc_tag_has_some_of_these_values: { int count = exe_i_pop(&exe); unsigned int values[count]; expected_value = __ch_malloc(expected_value); char * strp = expected_value; for (int j=0; j 0 */ GET_EMPTY_RET(ret) internal_entry_t exe = exe_pop(); bool_t should_we_go_in_fc_call= ( /* Precondition was valid */ (true == last_run_was_a_precondition) && (is_valid == precondition_result) ) || ( /* Precondition was valid, but has a type warning */ (true == last_run_was_a_precondition) && (tagwarn_type_of_unknown_tag_could_not_be_checked == precondition_result) ) || ( /* last was a normal function */ false == last_run_was_a_precondition ) ; #ifdef EXE_DEBUG //i_printstack(); //exe_printstack(); printf("last run was a precondition? %s\n", last_run_was_a_precondition?"true":"false"); printf("last run was a precondition? (2) %s\n", (true==last_run_was_a_precondition)?"true":"false"); printf(".. precondition_result=%s\n", get_parser_error_description(precondition_result)); printf(".. precondition_function=%s\n", get_parser_function_description(precondition_function)); printf("should we go in fc call? %s\n", ( /* last was successful precondition */ should_we_go_in_fc_call)?"true":"false"); printf("parsing function %s (%i) (linecode=%i)\n", get_parser_function_description( exe.function), exe.function, exe.lineno); #endif if ( should_we_go_in_fc_call ) { /* if true, execute function */ ret = call_exec_function(ctif, &ret, &exe ); #ifdef EXE_DEBUG printf("ret.returncode=%i, exe.is_precondition=%i is_valid=%i", ret.returncode, exe.is_precondition, is_valid); if (exe.function == fc_tag_has_valid_type) { printf("SSS tag %i has valid type: %i==%i (%s)\n", exe.tag, ret.returncode, is_valid, ret.value_found); } #endif if (false == exe.is_precondition) { if (exe.tag >= MINTAGS && exe.tag <= (MAXTAGS-1)) parser_state.called_tags[exe.tag]=true; /* mark tag that it has a rule */ } /* combine results */ if ( (true == exe.is_precondition) && (!( exe.function == fc_tag_has_valid_type && ( ret.returncode == tagerror_unexpected_type_found || ret.returncode == tag_does_not_exist) )) ) { /* precondition, next run depends on this result */ precondition_result = ret.returncode; if (NULL != ret.value_found) { free(ret.value_found); ret.value_found = NULL; } //if (NULL != expected_value) { // free(expected_value); // expected_value = NULL; //} } else { /* no precondition function */ /* if true, execute function */ full_res_t full; full.tag = exe.tag; full.function=exe.function; full.lineno=exe.lineno; full.returncode=ret.returncode; full.expected_value=NULL; full.found_value=NULL; /* if (NULL != expected_value) { if (ret.returncode != is_valid) { full.expected_value = expected_value; } else { free (expected_value); expected_value = NULL; } } */ if (ret.returncode != is_valid) { full.found_value = ret.value_found; } result_push( full ); precondition_result=is_valid; precondition_function = exe.function; } #ifdef EXE_DEBUG printf(" precondition_result=%i\n", precondition_result); #endif } else { // if precondition fails, return precondition if they have unexpected value! if (true == last_run_was_a_precondition) { #ifdef EXE_DEBUG printf("\t\t\t\t\t\t\t####################################\n"); printf("exe function: %s\n", get_parser_function_description(exe.function)); #endif if (exe.function == fc_internal_logic_combine_open) { /* clean logical or if precondition fails */ do { internal_entry_t l_exe = exe_pop(); #ifdef EXE_DEBUG printf("~~~ eliminating Logicals because PRE fails: %s\n", get_parser_function_description(l_exe.function)); #endif if (l_exe.function == fc_internal_logic_combine_close) break; } while (parser_state.exe_stackp > 0); #ifdef EXE_DEBUG printf("\t\t\t\t\t\t\t# ende\n"); #endif } ret.returncode = is_valid; } } last_run_was_a_precondition=exe.is_precondition; assert( ret.returncode != should_not_occur ); #ifdef EXE_DEBUG if (ret.returncode == is_valid) { printf("tmpresult = %s {returncode=%i, tag=%i}\n\nexe is precondition=%s\n", get_parser_error_description(ret.returncode), ret.returncode, exe.tag, exe.is_precondition==true?"true":"false");; }else{ printf("tmpresult = %s {returncode=%i, tag=%i}\n\nexe is precondition=%s\n", get_parser_error_description(ret.returncode), ret.returncode, exe.tag, exe.is_precondition==true?"true":"false");; } printf("==========\n"); #endif } while (parser_state.exe_stackp > 0); #ifdef EXE_DEBUG printf("all processed\n"); #endif #ifndef NOTAGCHECK for (int i = MINTAGS; i res=%s (%i)\n", i, get_parser_error_description(res.returncode), res.returncode); #endif full_res_t full; full.tag = i; full.function=fc_notag; full.lineno=-1; full.returncode=res.returncode; full.expected_value=NULL; full.found_value=NULL; result_push( full ); } } } #endif /* NOTAGCHECK */ } /* function to clean an execution plan */ void clean_plan () { } /* helper function for parser */ tag_t settag( tag_t tag) { parser_state.tag=tag; return tag; } tag_t settagref( tag_t tag) { parser_state.tagref=tag; return tag; } /* helper function for parser */ tag_t gettag( ) { return parser_state.tag;} int incrlineno() { parser_state.lineno++; #ifdef DEBUG printf("##lineno=%i\n", parser_state.lineno); #endif return parser_state.lineno; } /* helper function for parser */ int getlineno() { return parser_state.lineno;} /* int rule_tagorder_in_dsl( int tag ) { int prevtag = gettag(); #ifdef DEBUG printf ("tag '%i' found (prev tag was: '%i')\n", tag, prevtag); #endif if (prevtag > tag) { fprintf(stderr, "tag '%i' should be greater than previous tag '%i'\n", tag, prevtag); exit( -1 ); } } */ /* helper function for parser */ void commentline() { #ifdef DEBUG printf("commentline, %i\n", parser_state.lineno); #endif } /* helper function for parser */ /* void rule_should_not_occure(char* s) { #ifdef DEBUG printf("no parser rule matched after line %i (prev tag was %u): '%s'\n", getlineno(), gettag(), s); #endif } */ /* helper function for parser */ void set_mandatory() { #ifdef DEBUG printf("tag '%u' is mandatory\n", gettag()); #endif parser_state.req=mandatory; } /* helper function for parser */ void set_optional() { #ifdef DEBUG printf("tag '%u' is optional\n", gettag()); #endif parser_state.req=optional; parser_state.any_reference=any_ref; parser_state.tagref=gettag(); } /* helper function for parser */ void set_ifdepends() { #ifdef DEBUG printf("tag '%u' is set if depends\n", gettag()); #endif parser_state.req=ifdepends; } /* helper function for parser */ void set_optdepends() { #ifdef DEBUG printf("tag '%u' is set optional depends\n", gettag()); #endif parser_state.req=optdepends; } /* helper function for parser */ void regex_push( const char * regex_string) { pcre *re; int erroffset; const char * errorcode; re = pcre_compile( regex_string, /* the pattern */ 0, /* default options */ &errorcode, /* for error code */ &erroffset, /* for error offset */ NULL); /* no compile context */ if (NULL != re) { #ifdef DEBUG printf("regex found: '%s' in line %i\n", regex_string, parser_state.lineno); #endif pcre_free(re); r_push(regex_string); } else { fprintf(stderr, "regex compile error: %s at offset: %i in line %i\n", errorcode, erroffset, parser_state.lineno); exit(EXIT_FAILURE); } } /* helper function for parser */ void reset_valuelist() { parser_state.valuelist = 0; } /* helper function for parser */ void incr_values () { parser_state.valuelist++; } /* prepare functions for preconditions */ internal_entry_t prepare_internal_entry() { internal_entry_t p; p.i_stackp=0; p.regex_stackp=0; p.lineno=getlineno(); p.is_precondition=true; p.tag=parser_state.tagref; p.function=fc_tag_quiet; switch (parser_state.any_reference) { case no_ref: case any_ref: p.function=fc_tag_quiet; break; case only_ref: p.function=fc_tag_has_value_quiet; exe_i_push(&p, i_pop() ); break; case range_ref: p.function=fc_tag_has_value_in_range; exe_i_push(&p, i_pop() ); exe_i_push(&p, i_pop() ); break; case ntupel_ref: { int c = i_pop(); for (int i = 0; ifunction=fc_tag_has_value_in_range; } void build_functional_structure__ntupel(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("ntupel found\n"); #endif int c = i_pop(); for (int i = 0; ifunction=fc_tag_has_valuelist; } void build_functional_structure__only(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("only found\n"); #endif exe_i_push(e_p, i_pop() ); e_p->function=fc_tag_has_value; } void build_functional_structure__any(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("any found\n"); #endif e_p->function=fc_tag; } void build_functional_structure__regex(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("regex found\n"); #endif exe_regex_push(e_p, r_pop()); e_p->function=fc_tag_has_value_matching_regex; } void build_functional_structure__iccprofile(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("iccprofile found\n"); #endif e_p->function=fc_icc; } void build_functional_structure__datetime(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("datetime found\n"); #endif e_p->function=fc_datetime; } void build_functional_structure__printable_ascii(internal_entry_t * e_p) { #ifdef RULE_DEBUG printf("printable_ascii found\n"); #endif exe_regex_push(e_p, "^[[:print:]]*$"); e_p->function=fc_tag_has_value_matching_regex; } /* builds an entry structure holding function and their values */ void build_functional_structure(internal_entry_t * e_p, values_t val) { switch (val) { case range: build_functional_structure__range(e_p); break; case ntupel: build_functional_structure__ntupel(e_p); break; case only: build_functional_structure__only(e_p); break; case any: build_functional_structure__any(e_p); break; case regex: build_functional_structure__regex(e_p); break; case iccprofile: build_functional_structure__iccprofile(e_p); break; case datetime: build_functional_structure__datetime(e_p); break; case printable_ascii: build_functional_structure__printable_ascii(e_p); break; /* TODO: case sbit: { #ifdef RULE_DEBUG printf("sbit found\n"); #endif exe_regex_push(e_p, r_pop()); e_p->function=fc_tag_has_value; break; } */ default: fprintf(stderr, "unknown val %i, should not occur\n", val); exit(EXIT_FAILURE); } } /* adds preconditions to stack, first comes the real function, than the preconditions! */ void evaluate_req_and_push_exe(requirements_t req, internal_entry_t e) { assert( e.function != fc_dummy); #ifdef RULE_DEBUG printf("eval e=%s\n", get_parser_function_description(e.function)); #endif if (e.function == fc_internal_logic_combine_close) { #ifdef RULE_DEBUG printf("\n### eval req logical close found\n"); #endif e.function = fc_internal_logic_combine_close; exe_push(e); // TODO: exe_push(e); /* <-- logical close */ // TODO: exe_push(e); /* <-- real rule(s) */ for (int i = 0; i< parser_state.logical_elements; i++) { values_t val = v_pop(); e.function = fc_dummy; build_functional_structure(&e, val); /* <-- this builds the tiff test */ #ifdef RULE_DEBUG printf("###### i=%i e=%s\n", i, get_parser_function_description(e.function)); #endif exe_push(e); }; e.function=fc_internal_logic_combine_open; } exe_push(e); switch (req) { case ifdepends: { internal_entry_t p = prepare_internal_entry(); if (parser_state.mode & mode_enable_type_checks) { internal_entry_t z = e; z.is_precondition = true; z.function = fc_tag_has_valid_type; exe_push(z); } exe_push(p); break; } case mandatory: { if (parser_state.mode & mode_enable_type_checks) { internal_entry_t z = e; z.is_precondition = true; z.function = fc_tag_has_valid_type; exe_push(z); } break; } case optional: { internal_entry_t p = prepare_internal_entry(); if (parser_state.mode & mode_enable_type_checks) { internal_entry_t z = e; z.is_precondition = true; z.function = fc_tag_has_valid_type; exe_push(z); } exe_push(p); break; } case optdepends: { internal_entry_t pp; pp.i_stackp = 0; pp.regex_stackp = 0; pp.val_stackp=0; pp.lineno = getlineno(); pp.is_precondition = true; pp.tag = e.tag; pp.function = fc_tag_quiet; internal_entry_t p = prepare_internal_entry(); if (parser_state.mode & mode_enable_type_checks) { internal_entry_t z = e; z.is_precondition = true; z.function = fc_tag_has_valid_type; exe_push(z); } exe_push(p); exe_push(pp); break; } default: { fprintf(stderr, "unknown parserstate.req (%i), should not occur\n", parser_state.req); exit(EXIT_FAILURE); } } } void set_rule_logical_open() { #ifdef RULE_DEBUG printf("rule_add_logical_config\n"); #endif /* internal_entry_t e; e.tag = parser_state.tag; e.i_stackp=0; e.regex_stackp=0; e.lineno=getlineno(); e.is_precondition=false; e.function=fc_internal_logic_combine_open; //exe_push(e); */ parser_state.within_logical_or=true; //evaluate_req_and_push_exe( parser_state.req, e); //rule_addtag_config(); } void incr_logical_elements() { #ifdef RULE_DEBUG printf("incr logical elements to %i\n", parser_state.logical_elements+1); #endif parser_state.logical_elements++; } /* helper function for parser */ void set_rule_logical_close() { #ifdef RULE_DEBUG printf("reset_logical_list\n"); #endif internal_entry_t e; e.tag = parser_state.tag; e.i_stackp=0; e.regex_stackp=0; e.val_stackp = 0; e.lineno=getlineno(); e.is_precondition=false; e.function=fc_internal_logic_combine_close; //exe_push(e); evaluate_req_and_push_exe( parser_state.req, e); parser_state.within_logical_or=false; parser_state.logical_elements=0; } /* this adds the config of a tagline to execution plan * HINT: order of calling arguments from stacks is IMPORTANT! */ void rule_addtag_config() { if( parser_state.val_stackp > 0) { #ifdef RULE_DEBUG printf("rule_addtag_config\n"); #endif internal_entry_t e; e.i_stackp=0; e.regex_stackp=0; e.lineno=getlineno(); e.is_precondition=false; /* no precondition as default */ e.tag = parser_state.tag; #ifdef RULE_DEBUG printf( "try to match tagline at line %i\n", e.lineno); #endif /* typedef struct internal_entry_s { int lineno; int count_of_arguments; int is_precondition; tag_t tag; logic_t is_combined; function_t function_used; } internal_entry_t; */ /* HINT: order of evaluating last val and last req is IMPORTANT! */ #ifdef RULE_DEBUG v_printstack(); i_printstack(); r_printstack(); #endif /* stack should be organized as: * [ruleA] * [preconditionA] <- optional * [prepreconditionA] <- optional * [ruleB] * [preconditionB] <- optional * [prepreconditionB] <- optional */ do { values_t val = v_pop(); #ifdef RULE_DEBUG printf("was ist noch auf stacks?\n"); v_printstack(); i_printstack(); r_printstack(); printf("auf exe stack ist nun:\n"); exe_printstack(); printf("-----\n"); #endif e.function = fc_dummy; build_functional_structure(&e, val); /* <-- this builds the tiff test */ /* set predicate if and only if lastreq = depends */ /* HINT: order of evaluating last val and last req is IMPORTANT! */ /* HINT: order of calling arguments from stacks is IMPORTANT! */ evaluate_req_and_push_exe( parser_state.req, e); /* <-- this sets the predicates */ } while ( parser_state.val_stackp > 0); reset_valuelist(); parser_state.any_reference = 0; #ifdef RULE_DEBUG printf("ENDE rule_addtag\n"); exe_printstack(); printf("\n\n\n"); #endif } } /* set_mode */ void set_mode(modes_t mode) { #ifdef RULE_DEBUG printf("Mode=%i at line=%i (needs to be implemented)\n", mode, parser_state.lineno ); #endif internal_entry_t e; e.i_stackp=0; e.regex_stackp=0; e.lineno=getlineno(); e.is_precondition=false; /* no precondition as default */ e.tag = parser_state.tag; switch (mode) { case mode_enable_offset_checks: { e.function = fc_all_offsets_are_word_aligned; exe_push(e); e.function = fc_all_offsets_are_used_once_only; exe_push(e); e.function = fc_all_offsets_are_not_zero; exe_push(e); break; } case mode_enable_ifd_checks: { e.function = fc_all_IFDs_are_word_aligned; exe_push(e); e.function = fc_tagorder; exe_push(e); break; } case mode_baseline: { e.function = fc_has_only_one_ifd; exe_push(e); break; } case mode_enable_type_checks: { /* nothing, because we must enable it only in rule_addtag_config */ } } parser_state.mode |= mode; } /* reset the parser state */ void reset_parser_state() { parser_state.any_reference=0; parser_state.exe_stackp=0; parser_state.includedepth=0; parser_state.i_stackp=0; parser_state.lineno=1; parser_state.regex_stackp=0; parser_state.req=0; parser_state.result_stackp=0; parser_state.tag=0; parser_state.tagref=-1; parser_state.val_stackp=0; parser_state.valuelist=0; parser_state.mode=0; parser_state.within_logical_or=false; parser_state.logical_elements=0; for (int i=0; i= 1) { fprintf( stderr, "only include depth of %i is supported\n", MAXINCLUDEDEPTH); exit (EXIT_FAILURE); } parser_state.includedepth++; printf("Include=%s\n", include_file); FILE * cfg = fopen(include_file, "r"); if (NULL == cfg) { fprintf( stderr, "file '%s' could not be opened\n", include_file); exit (EXIT_FAILURE); }; clean_plan(); yycontext ctx2; memset(&ctx2, 0, sizeof(yycontext)); FILE * old_stream = parser_state.stream; int old_lineno = parser_state.lineno; printf("At lineno %i, file %s, switching to include file %s\n", old_lineno, "", include_file); parser_state.lineno=1; parser_state.stream=cfg; while (yyparse(&ctx2)) /* repeat until EOF */ ; yyrelease(&ctx2); parser_state.includedepth--; printf("End of Include=%s\n", include_file); parser_state.stream = old_stream; parser_state.lineno = old_lineno; fclose(cfg); } /* function to parse a config file from STDIN */ void parse_plan () { reset_parser_state(); /*/ r_printstack(); printf("rp=%i\n", parser_state.regex_stackp); r_push("foo"); r_printstack(); printf("rp=%i\n", parser_state.regex_stackp); const char * v = r_pop(); r_printstack(); printf("rp=%i %s\n", parser_state.regex_stackp, v); fprintf(stderr, "----\n"); r_pop(); */ yycontext ctx; memset(&ctx, 0, sizeof(yycontext)); parser_state.stream=stdin; while (yyparse(&ctx)) /* repeat until EOF */ ; yyrelease(&ctx); } /* function to parse a config file from file stream */ void parse_plan_via_stream( FILE * file ) { reset_parser_state(); yycontext ctx; memset(&ctx, 0, sizeof(yycontext)); parser_state.stream=file; while (yyparse(&ctx)) /* repeat until EOF */ ; yyrelease(&ctx); } /* function to parse a config file */ void parse_plan_via_file( const char * cfg_file ) { FILE * cfg = fopen(cfg_file, "r"); if (NULL == cfg) { fprintf( stderr, "file '%s' could not be opened\n", cfg_file); exit (EXIT_FAILURE); }; clean_plan(); parse_plan_via_stream( cfg ); fclose(cfg); } /* set parse error * @param msg describes the details about what was going wrong * @param yytext gives context of the error */ void set_parse_error(char * msg, char * yytext) { fprintf(stderr, "%s at line %i (error at '%s')\n", msg, parser_state.lineno, yytext); exit(EXIT_FAILURE); } void clean_plan_results() { for (int i=parser_state.result_stackp-1; i >= 0; --i) { if (NULL != parser_state.result_stack[i].found_value) { free( parser_state.result_stack[i].found_value ); parser_state.result_stack[i].found_value=NULL; } if (NULL != parser_state.result_stack[i].expected_value) { free( parser_state.result_stack[i].expected_value ); parser_state.result_stack[i].expected_value=NULL; } } } /* prints a plan (list) of functions and their results*/ ret_t print_plan_results(retmsg_t * actual_render) { GET_EMPTY_RET(res) #ifdef DEBUG printf("print plan results:\n"); printf("####################(\n"); for (int i=parser_state.result_stackp-1; i >= 0; --i) { full_res_t parser_result = parser_state.result_stack[i]; if (0 == parser_result.returncode) { printf( "i=%i retcode=%i ", i, parser_result.returncode); } else { printf( "i=%i retcode=%i ", i, parser_result.returncode); } printf( "value-> %s lineno=%i\n", parser_result.found_value, parser_result.lineno); } printf(")####################\n"); printf("reduced\n"); #endif #ifdef EXE_DEBUG result_printstack(); #endif reduce_results(); #ifdef EXE_DEBUG result_printstack(); #endif int count_of_valid_results = 0; for (int i=parser_state.result_stackp-1; i >= 0; --i) { full_res_t parser_result = parser_state.result_stack[i]; #ifdef DEBUG printf( "i=%i retcode=%s (%i) lineno=%i tag=%i %s\n", i, get_parser_error_description(parser_result.returncode), parser_result.returncode, parser_result.lineno, parser_result.tag, parser_result.found_value); #endif returncode_t returncode = parser_result.returncode; /* fill render pipeline */ uint16 tag = parser_result.tag; /* fill with errorcodes */ rm_type_t type= rm_default; switch ( returncode ) { /* add rm_type */ case is_valid: type = rm_is_valid; count_of_valid_results++; break; case parser_logicalor_error: type = rm_logicalor_error; break; case could_not_allocate_memory: case could_not_print: case should_not_occur: assert ( 1 ); case code_error_streampointer_empty: case code_error_filedescriptor_empty: case code_error_ctif_empty: case pcre_compile_error: case tiff_seek_error_header: case tiff_read_error_header: case tiff_seek_error_offset: case tiff_read_error_offset: type = rm_hard_error; break; default: type = rm_error; break; } __add_to_render_pipeline_via_strncpy(&actual_render, "", type); /* fill with tag infos */ if (tag > 0) { char tagstr [VALUESTRLEN]; snprintf(tagstr, VALUESTRLEN, "tag %i (%s)", tag, TIFFTagName(tag)); __add_to_render_pipeline_via_strncpy(&actual_render, tagstr, rm_tag); } else { __add_to_render_pipeline_via_strncpy(&actual_render, "general", rm_mode); } /* fill with rule infos */ __add_to_render_pipeline_via_strncpy(&actual_render, get_parser_function_description(parser_result.function), rm_rule); if (parser_result.expected_value != NULL) { __add_to_render_pipeline_via_strncpy(&actual_render, parser_result.expected_value, rm_expected); } else { // __add_to_render_pipeline_via_strncpy(&actual_render, "nothing", rm_expected); } /* fill with value found */ if (returncode != is_valid) { __add_to_render_pipeline_via_strncpy(&actual_render, get_parser_error_description(returncode), rm_error_description); if (parser_result.found_value != NULL) { __add_to_render_pipeline_via_strncpy(&actual_render, parser_result.found_value, rm_value); } else { //__add_to_render_pipeline_via_strncpy(&actual_render, "nothing", rm_value); } } /* fill with lineno */ char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "%i", parser_result.lineno); __add_to_render_pipeline_via_strncpy(&actual_render, msg, rm_lineno); /* fill with newline */ __add_to_render_pipeline_via_strncpy(&actual_render, "", rm_endrule); if (type == rm_hard_error) { goto harderrors; } /* printf( "%s", renderer( parser_state.result_stack[i].result)); */ } harderrors: { int errors = (parser_state.result_stackp -count_of_valid_results ); char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "Found %i errors", errors) ; if (errors > 0) { res.returncode = is_error; __add_to_render_pipeline_via_strncpy(&actual_render, msg, rm_error); __add_to_render_pipeline_via_strncpy(&actual_render, "No, the given tif is not valid :(", rm_summary_invalid); } else { res.returncode = is_valid; __add_to_render_pipeline_via_strncpy(&actual_render, msg, rm_is_valid); __add_to_render_pipeline_via_strncpy(&actual_render, "Yes, the given tif is valid :)", rm_summary_valid); } } __add_to_render_pipeline_via_strncpy(&actual_render, " ", rm_endtiff); clean_plan_results(); return res; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/risk_analyzer/000077500000000000000000000000001327425157300176145ustar00rootroot00000000000000checkit_tiff-0.4.2/src/risk_analyzer/lst_offset_mappings.c000066400000000000000000000300471327425157300240320ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015/2016 * licensed under conditions of libtiff * (see file LICENSE) * */ #include "check.h" #include "check_helper.h" #include #include void add_mem_entry(mem_map_t * memmap_p, uint32 offset, uint32 count, memtype_t type) { mem_map_t memmap = *( memmap_p ); assert(NULL != memmap.base_p); assert(0 < memmap.max_entries); assert(memmap.count < memmap.max_entries); assert(type < mt_END_marker); mem_map_entry_t * memmap_it_p = memmap.base_p; memmap_it_p = memmap.base_p + memmap.count; memmap_it_p->offset=offset; memmap_it_p->count=count; memmap_it_p->mem_type=type; memmap.count++; assert( memmap.max_entries > memmap.count); *( memmap_p) = memmap; } int compare_memmap(void const * lhs, void const * rhs) { mem_map_entry_t left = *((mem_map_entry_t *) lhs); mem_map_entry_t right = *((mem_map_entry_t *) rhs); return ((left.offset) - (right.offset)); } /* TODO: add support for StripOffsets and StripByteCounts */ mem_map_t * scan_mem_map(ctiff_t * ctif) { assert( NULL != ctif); static mem_map_t memmap; memmap.count = 0; memmap.base_p = NULL; memmap.max_entries = 2048; memmap.base_p = malloc (sizeof(mem_map_entry_t) * memmap.max_entries); if (NULL == memmap.base_p) { perror ("could not allocate mem for memmap, abort"); } /* size of tiff file in bytes */ memmap.max_len = ctif->streamlen; /* header */ add_mem_entry( &memmap, 0, 4, mt_constant); /* IFD0 Offset */ add_mem_entry( &memmap, 4, 4, mt_offset_to_ifd0); /* IFDO */ uint32 ifd = get_ifd0_pos( ctif ); uint16 count = get_ifd0_count( ctif); add_mem_entry( &memmap, ifd, 2, mt_ifd); /* count of tags in ifd */ int ifdbase=2+ifd; /* iterate through IFD0 entries */ uint16 tagidx; ifd_entry_t stripoffset_entry; for (tagidx = 0; tagidx< count; tagidx++) { add_mem_entry( &memmap, ifdbase+(tagidx*12), 8, mt_ifd); /* tagid, field type, count */ ifd_entry_t ifd_entry = TIFFGetRawTagIFDListEntry( ctif, tagidx ); uint32 tag = TIFFGetRawTagListEntry( ctif, tagidx); TIFFDataType datatype = TIFFGetRawTagType( ctif, tag); int datasize; switch (datatype) { case TIFF_ASCII: datasize = 1; break; case TIFF_LONG: datasize = 4; break; case TIFF_SHORT: datasize = 2; break; case TIFF_BYTE: datasize = 1; break; case TIFF_UNDEFINED: datasize = 1; break; case TIFF_RATIONAL: datasize = 8; break; case TIFF_SSHORT: datasize = 2; break; case TIFF_SBYTE: datasize = 1; break; case TIFF_SLONG: datasize = 4; break; case TIFF_SRATIONAL: datasize = 8; break; case TIFF_FLOAT: datasize = 4; break; case TIFF_DOUBLE: datasize = 8; break; default: fprintf(stderr, "unknown datatype %i, possible a program error", datatype); exit(EXIT_FAILURE); } uint32 offset = ifd_entry.data32offset; uint16 count = ifd_entry.count; if (tag == TIFFTAG_STRIPOFFSETS) { if (ifd_entry.value_or_offset == is_offset) { add_mem_entry( &memmap, ifdbase+(tagidx*12)+8,4,mt_ifd_offset_to_standardized_value ); add_mem_entry( &memmap, offset, ((uint32) count)*datasize, mt_ifd_offset_to_stripoffsets ); } else if (ifd_entry.value_or_offset==is_value) { add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_embedded_standardized_value ); } stripoffset_entry=ifd_entry; } else if (ifd_entry.value_or_offset==is_offset) { /* offset */ if (tag < 32768) { /* standard tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_offset_to_standardized_value ); add_mem_entry( &memmap, offset, ((uint32) count)*datasize, mt_standardized_value ); } else if (tag < 65000) { /* registered tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_offset_to_registered_value ); add_mem_entry( &memmap, offset, ((uint32) count)*datasize, mt_registered_value ); } else { /* private tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_offset_to_private_value ); add_mem_entry( &memmap, offset, ((uint32) count)*datasize, mt_private_value ); } } else if (ifd_entry.value_or_offset==is_value) { /* embedded value */ if (tag < 32768) { /* standard tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_embedded_standardized_value ); } else if (tag < 65000) { /* registered tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_embedded_registered_value ); } else { /* private tag */ add_mem_entry( &memmap, ifdbase+(tagidx*12)+8, 4,mt_ifd_embedded_private_value ); } } } /* check next IFD mark */ // uint32 offset = get_ifd0_pos(ctif ); // uint32 IFDn = get_next_ifd_pos( ctif, offset ); // printf("IFD: offset=%i, IFD0=%i IFDn=%i ifd+count=%i\n", offset, ifd, IFDn, ifdbase+12*count); add_mem_entry( &memmap, ifdbase+12*count, 4, mt_offset_to_ifd); /* handle stripoffset data */ //printf("ifd_count=%i, stripoffset_count=%i\n", stripoffset_entry.count, stripoffset_count); uint32 stripoffset_values[stripoffset_entry.count]; switch (stripoffset_entry.datatype) { case TIFF_LONG: { /* value */ if (stripoffset_entry.value_or_offset == is_value) { for (uint32 i=0; i< stripoffset_entry.count; i++) { stripoffset_values[i] = stripoffset_entry.data32; } } /* offset */ if (stripoffset_entry.value_or_offset == is_offset) { offset_t offset; ret_t ret = read_offsetdata(ctif, stripoffset_entry.data32offset, stripoffset_entry.count, stripoffset_entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { fprintf(stderr, "error reading offset data, stripoffset_entry.count has size %u, resulting address %zu, but only offset to %lu is possible\n", stripoffset_entry.count, ((uint64) stripoffset_entry.count*sizeof(uint32)), (uint64) 0xffffffff); exit(EXIT_FAILURE); } uint32 * p = offset.data32p; if ((uint64) stripoffset_entry.count*sizeof(uint32) > 0xffffffff) { fprintf(stderr, "stripoffset_entry.count has size %u, resulting address %zu, but only offset to %lu is possible\n", stripoffset_entry.count, ((uint64) stripoffset_entry.count*sizeof(uint32)), (uint64) 0xffffffff); exit(EXIT_FAILURE); } for (uint32 i=0; i< stripoffset_entry.count; i++) { uint32 pval = *p; if (is_byteswapped(ctif)) { TIFFSwabLong(&pval); } stripoffset_values[i]=pval; p++; } } break; } case TIFF_SHORT: { /* value */ if (stripoffset_entry.value_or_offset == is_value) { for (uint32 i=0; i< stripoffset_entry.count; i++) { stripoffset_values[i]= stripoffset_entry.data16[i]; } } /* offset */ if (stripoffset_entry.value_or_offset == is_offset) { offset_t offset; ret_t ret = read_offsetdata(ctif, stripoffset_entry.data32offset, stripoffset_entry.count, stripoffset_entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { fprintf(stderr, "error reading offset data, stripoffset_entry.count has size %u, resulting address %zu, but only offset to %lu is possible\n", stripoffset_entry.count, ((uint64) stripoffset_entry.count*sizeof(uint32)), (uint64) 0xffffffff); exit(EXIT_FAILURE); } uint16 * p = offset.data16p; if ((uint64) stripoffset_entry.count*sizeof(uint16) > 0xffffffff) { fprintf(stderr, "stripoffset_entry.count has size %u, resulting address %zu, but only offset to %lu is possible\n", stripoffset_entry.count, ((uint64) stripoffset_entry.count*sizeof(uint16)), (uint64) 0xffffffff); exit(EXIT_FAILURE); } for (uint32 i=0; i< count; i++) { uint16 pval = *p; if (is_byteswapped(ctif)) { TIFFSwabShort(&pval); } stripoffset_values[i]=pval; p++; } } break; } default: { perror("stripoffset_entry.datatype has an unexpected value, possible a program error\n"); exit(EXIT_FAILURE); } } //printf("count=%i\n", stripoffset_entry.count); /*TODO: for (int i=0; i< stripoffset_entry.count; i++) { uint32 rawstriplen = TIFFRawStripSize(ctif->tif, i); //printf("OFFSET: p[%i]=%u len=%i\n", i,stripoffset_values[i], rawstriplen); add_mem_entry( &memmap, stripoffset_values[i], rawstriplen, mt_stripoffset_value); } */ /* sort entries by offset */ qsort(memmap.base_p, memmap.count, sizeof( mem_map_entry_t), compare_memmap); /* printf("memmap before HOLE detection\n"); print_mem_map( &memmap ); printf("----------------------------\n"); */ /* add all unused areas */ uint32 memmap_orig_count = memmap.count; for (uint32 j=1; j< memmap_orig_count; j++) { mem_map_entry_t * prev=memmap.base_p+j-1; mem_map_entry_t * act =memmap.base_p+j; uint32 estimated_offset = (prev->offset + prev->count); if (estimated_offset < act->offset) { /* found a hole */ printf("HOLE FOUND at %u\n", estimated_offset); printf("\tprev->offset=%u prev->count=%u estimated=%u\n", prev->offset, prev->count, estimated_offset); printf("\tact->offset=%u act->count=%u\n", act->offset, act->count); add_mem_entry( &memmap, estimated_offset, (act->offset -estimated_offset), mt_unused); } } /* sort entries by offset again */ qsort(memmap.base_p, memmap.count, sizeof( mem_map_entry_t), compare_memmap); /* add unused area at end */ mem_map_entry_t * last = memmap.base_p + memmap.count-1; uint32 estimated_offset = (last->offset + last->count); if (memmap.max_len > estimated_offset) { printf("HOLE (at end) FOUND at %u\n", estimated_offset); add_mem_entry( &memmap, estimated_offset, (memmap.max_len -estimated_offset), mt_unused); } /* sort entries by offset again */ qsort(memmap.base_p, memmap.count, sizeof( mem_map_entry_t), compare_memmap); return &memmap; } void print_mem_map( mem_map_t * memmap_p ) { assert(NULL != memmap_p); mem_map_t memmap = *( memmap_p ); printf("size of file is %u bytes\n", memmap.max_len); for (int j=0; j< memmap.count; j++) { mem_map_entry_t * i=memmap.base_p+j; printf ("entry=%03i, offset_start=%10u, count=%10u, offset_next=%10u, [%02i], type=%s\n", j,i->offset, i->count, (i->offset + i->count), i->mem_type, memtype_string[i->mem_type]); } } void print_mem_stats( mem_map_t * memmap_p) { uint32 size = memmap_p->max_len; uint32 stat[ mt_END_marker ]; uint32 counted=0; for (int i=0; i< mt_END_marker; i++) { stat[i]=0; } for (int j=0; j< memmap_p->count; j++) { mem_map_entry_t * i=memmap_p->base_p+j; stat[i->mem_type]+= i->count; counted+=i->count; } for (int i=0; i #include /** check if date / time values are within correct ranges * @param year year * @param month month * @param day day * @param hour hour * @param min min * @param sec sec * @return 0 if success, otherwise -1 */ int test_plausibility (int * year, int * month, int * day, int * hour, int * min, int * sec) { #ifdef DEBUG printf ("found: y=%d m=%d d=%d h=%d m=%d s=%d\n", *year, *month, *day, *hour, *min, *sec); #endif if ( 1500 < *year && 2100 > *year && 0 < *month && 13 > *month && 0 < *day && 32 > *day && 0 <= *hour && 24 > *hour && 0 <= *min && 60 > *min && 0 <= *sec && 60 > *sec ) { return 0; } else { return -1; } } /** loads a tiff, fix it if needed, stores tiff * @param filename filename which should be processed, repaired */ ret_t check_datetime(ctiff_t * ctif ) { GET_EMPTY_RET(ret) tifp_check( ctif); ret_t rc=check_tag_quiet(ctif, TIFFTAG_DATETIME); if (rc.returncode != is_valid) return rc; /* find date-tag and fix it */ TIFFDataType datatype = TIFFGetRawTagType( ctif, TIFFTAG_DATETIME ); if (datatype != TIFF_ASCII) { char array[VALUESTRLEN]; snprintf(array, sizeof(array), "type:%s", TIFFTypeName(datatype)); ret = set_value_found_ret( &ret, array); ret.returncode = tagerror_unexpected_type_found; return ret; } uint32 count=0; char *datetime=NULL; ret = TIFFGetFieldASCII(ctif, TIFFTAG_DATETIME, &datetime, &count); if (ret.returncode != is_valid) return ret; // printf("DATETIME='%s'\n", datetime); int day=0; int month=0; int year=0; int hour=0; int min=0; int sec=0; int r = 0; for (uint32 i=0; i /* #define DEBUG */ ret_t check_tag_has_some_of_these_values(ctiff_t * ctif, tag_t tag, int count, const unsigned int * values) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; const unsigned int * p = values; TIFFDataType datatype = TIFFGetRawTagType( ctif, tag ); switch (datatype) { case TIFF_LONG: { p = values; ret_t tmp_res; for (int i=0; i< count; i++) { #ifdef DEBUG printf("### value = %u", *p); #endif tmp_res = check_tag_has_u32value(ctif, tag, *p); if (tmp_res.returncode == 0) return tmp_res; p++; } uint32 * valp = NULL; uint32 vcount=0; ret = TIFFGetFieldLONG(ctif, tag, &valp, &vcount); if (vcount >0) { uint32 val= *valp; char value[VALUESTRLEN]; snprintf(value, sizeof(value), "%u", val); ret.value_found = strncpy(ret.value_found, value, VALUESTRLEN); ret.returncode = tagerror_value_differs; }; return ret; /* break; */ } case TIFF_SHORT: { p = values; ret_t tmp_res; for (int i=0; i< count; i++) { #ifdef DEBUG printf("### value = %u", *p); #endif tmp_res = check_tag_has_u16value(ctif, tag, *p); if (tmp_res.returncode == 0) return tmp_res; p++; } uint16 * valp = NULL; uint32 vcount=0; ret = TIFFGetFieldSHORT(ctif, tag, &valp, &vcount); if (vcount >0) { uint16 val= *valp; char value[VALUESTRLEN]; snprintf(value, sizeof(value), "%u", val); ret.value_found = strncpy(ret.value_found, value, VALUESTRLEN); ret.returncode = tagerror_value_differs; } return ret; /* break; */ } case TIFF_RATIONAL: { p = values; ret_t tmp_res; for (int i=0; i< count; i++) { #ifdef DEBUG printf("### value = %u", *p); #endif tmp_res = check_tag_has_fvalue(ctif, tag, *p); if (tmp_res.returncode == 0) return tmp_res; p++; } float * valp = NULL; uint32 vcount=0; ret = TIFFGetFieldRATIONAL(ctif, tag, &valp, &vcount); if (count >0) { float val = * valp; char value[VALUESTRLEN]; snprintf(value, sizeof(value), "%f", val); ret.value_found = strncpy(ret.value_found, value, VALUESTRLEN); ret.returncode = tagerror_value_differs; } return ret; /* break; */ } default: /* none */ { ret.value_found = strncpy(ret.value_found, TIFFTypeName(datatype), VALUESTRLEN); ret.returncode = tagerror_unexpected_type_found; return ret; } } ret.returncode=should_not_occur; assert( ret.returncode != should_not_occur); return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_valid_asciivalue.c000066400000000000000000000031721327425157300250630ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" /* #define DEBUG */ /* checks if TIF with tag and type ASCII */ ret_t check_tag_has_valid_asciivalue(ctiff_t * ctif, tag_t tag) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; TIFFDataType datatype = TIFFGetRawTagType( ctif, tag ); #ifdef DEBUG printf("### datatype=%i \n", datatype); #endif char *string=NULL; uint32 count=0; int r = 0; if (datatype == TIFF_ASCII) { ret = TIFFGetFieldASCII(ctif, tag, &string, &count); if (0 < count) { /* there exists a tag */ for (uint32 i=0; i /* #define DEBUG */ /* checks if TIF has a specified tag */ ret_t check_tag_has_valid_type(ctiff_t * ctif, tag_t tag) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); assert(ret.returncode != should_not_occur); if (ret.returncode != is_valid) return ret; TIFFDataType datatype = TIFFGetRawTagType( ctif, tag ); #ifdef DEBUG printf("### datatype=%i \n", datatype); #endif int res = 0; switch (tag) { case TIFFTAG_ARTIST: res=(datatype == TIFF_ASCII); break; case TIFFTAG_BADFAXLINES: res=(datatype == TIFF_LONG); break; case TIFFTAG_BITSPERSAMPLE: res=(datatype == TIFF_SHORT); break; case TIFFTAG_CELLLENGTH: res=(datatype == TIFF_SHORT); break; case TIFFTAG_CELLWIDTH: res=(datatype == TIFF_SHORT); break; case TIFFTAG_COLORMAP: res=(datatype == TIFF_SHORT); break; case TIFFTAG_COMPRESSION: res=(datatype == TIFF_SHORT); break; case TIFFTAG_COPYRIGHT: res=(datatype == TIFF_ASCII); break; case TIFFTAG_DATETIME: res=(datatype == TIFF_ASCII); break; case TIFFTAG_DOCUMENTNAME: res=(datatype == TIFF_ASCII); break; case TIFFTAG_DOTRANGE: res=(datatype == TIFF_BYTE) || (datatype == TIFF_SHORT);; break; case TIFFTAG_EXIFIFD: res=(datatype == TIFF_LONG); break; /* Exif Spec 2.3 */ case TIFFTAG_EXTRASAMPLES: res=(datatype == TIFF_SHORT); break; case TIFFTAG_FILLORDER: res=(datatype == TIFF_SHORT); break; case TIFFTAG_FREEBYTECOUNTS: res=(datatype == TIFF_LONG); break; case TIFFTAG_FREEOFFSETS: res=(datatype == TIFF_LONG); break; case TIFFTAG_GPSIFD: res=(datatype == TIFF_LONG); break; case TIFFTAG_GRAYRESPONSECURVE: res=(datatype == TIFF_SHORT); break; case TIFFTAG_GRAYRESPONSEUNIT: res=(datatype == TIFF_SHORT); break; case TIFFTAG_HALFTONEHINTS: res=(datatype == TIFF_SHORT); break; case TIFFTAG_HOSTCOMPUTER: res=(datatype == TIFF_ASCII); break; case TIFFTAG_ICCPROFILE: res=(datatype == TIFF_UNDEFINED); break; case TIFFTAG_IMAGEDEPTH: res=(datatype == TIFF_LONG); break; case TIFFTAG_IMAGEDESCRIPTION: res=(datatype == TIFF_ASCII); break; case TIFFTAG_IMAGELENGTH: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT);; break; case TIFFTAG_IMAGEWIDTH: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT);; break; case TIFFTAG_INKNAMES: res=(datatype == TIFF_ASCII); break; case TIFFTAG_INKSET: res=(datatype == TIFF_SHORT); break; case TIFFTAG_INTEROPERABILITYIFD:res=(datatype == TIFF_LONG); break; /* Exif Spec 2.3 */ case TIFFTAG_JPEGPROC: res=(datatype == TIFF_SHORT); break; case TIFFTAG_MAKE: res=(datatype == TIFF_ASCII); break; case TIFFTAG_MAXSAMPLEVALUE: res=(datatype == TIFF_SHORT); break; case TIFFTAG_MINSAMPLEVALUE: res=(datatype == TIFF_SHORT); break; case TIFFTAG_MODEL: res=(datatype == TIFF_ASCII); break; case TIFFTAG_NUMBEROFINKS: res=(datatype == TIFF_SHORT); break; case TIFFTAG_ORIENTATION: res=(datatype == TIFF_SHORT); break; case TIFFTAG_OSUBFILETYPE: res=(datatype == TIFF_SHORT); break; case TIFFTAG_PAGENUMBER: res=(datatype == TIFF_SHORT); break; case TIFFTAG_PHOTOMETRIC: res=(datatype == TIFF_SHORT); break; case TIFFTAG_PLANARCONFIG: res=(datatype == TIFF_SHORT); break; case TIFFTAG_PREDICTOR: res=(datatype == TIFF_SHORT); break; case TIFFTAG_PRIMARYCHROMATICITIES: res=(datatype == TIFF_RATIONAL); break; case TIFFTAG_REFERENCEBLACKWHITE: res=(datatype == TIFF_LONG); break; case TIFFTAG_RESOLUTIONUNIT: res=(datatype == TIFF_SHORT); break; case TIFFTAG_RICHTIFFIPTC: res=(datatype == TIFF_UNDEFINED) || (datatype == TIFF_BYTE); break; case TIFFTAG_ROWSPERSTRIP: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_SAMPLEFORMAT: res=(datatype == TIFF_SHORT); break; case TIFFTAG_SAMPLESPERPIXEL: res=(datatype == TIFF_SHORT); break; case TIFFTAG_SMAXSAMPLEVALUE: res=(datatype == TIFF_ANY); break; case TIFFTAG_SMINSAMPLEVALUE: res=(datatype == TIFF_ANY); break; case TIFFTAG_SOFTWARE: res=(datatype == TIFF_ASCII); break; case TIFFTAG_STRIPBYTECOUNTS: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_STRIPOFFSETS: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_SUBFILETYPE: res=(datatype == TIFF_LONG); break; case TIFFTAG_SUBIFD: res=(datatype == TIFF_LONG); break; /* TIFF technical note 1 */ case TIFFTAG_T4OPTIONS: res=(datatype == TIFF_LONG); break; case TIFFTAG_T6OPTIONS: res=(datatype == TIFF_LONG); break; case TIFFTAG_TARGETPRINTER: res=(datatype == TIFF_ASCII); break; case TIFFTAG_THRESHHOLDING: res=(datatype == TIFF_SHORT); break; case TIFFTAG_TILEBYTECOUNTS: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_TILELENGTH: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_TILEOFFSETS: res=(datatype == TIFF_LONG); break; case TIFFTAG_TILEWIDTH: res=(datatype == TIFF_LONG) || (datatype == TIFF_SHORT); break; case TIFFTAG_TRANSFERFUNCTION: res=(datatype == TIFF_SHORT); break; case TIFFTAG_WHITEPOINT: res=(datatype == TIFF_RATIONAL); break; case TIFFTAG_XRESOLUTION: res=(datatype == TIFF_RATIONAL); break; case TIFFTAG_YRESOLUTION: res=(datatype == TIFF_RATIONAL); break; default: { #ifdef DEBUG printf("for tag %i no explicite type check implemented\n", tag); #endif ret = set_value_found_ret(&ret, TIFFTypeName(datatype)); ret.returncode = tagwarn_type_of_unknown_tag_could_not_be_checked; return ret; }; } #ifdef DEBUG printf("for tag %i found datatype=%s, res=%i\n", tag, TIFFTypeName(datatype), res); #endif if (!res) { ret = set_value_found_ret(&ret, TIFFTypeName(datatype)); ret.returncode = tagerror_unexpected_type_found; return ret; } else { ret.returncode = is_valid; return ret; } /* we check only count, because we evaluate only int-values */ ret.returncode = should_not_occur; assert(ret.returncode != should_not_occur); return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_value.c000066400000000000000000000010201327425157300226610ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #include /* #define DEBUG */ ret_t check_tag_has_value(ctiff_t * ctif, tag_t tag, unsigned int value) { tifp_check( ctif); return check_tag_has_value_quiet( ctif, tag, value); } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_value_in_range.c000066400000000000000000000133261327425157300245370ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #define _GNU_SOURCE #include "check.h" #include "check_helper.h" #include /* #define DEBUG */ ret_t check_tag_has_value_in_range(ctiff_t * ctif, tag_t tag, unsigned int a, unsigned int b) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; if (a > b) { unsigned int c=a; a=b; b=c; } TIFFDataType datatype = TIFFGetRawTagType( ctif, tag ); switch (datatype) { case TIFF_LONG: { uint32 * valp = NULL; uint32 found=0; ret=TIFFGetFieldLONG(ctif, tag, &valp, &found); if (ret.returncode != is_valid) return ret; if (1 == found) { uint32 val= *valp; if ((val >= a && val <= b )) { ret.returncode=is_valid; free( valp); return ret; } else { free(valp); char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found value %u", val); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } } else { if (NULL != valp) { free(valp); valp=NULL; } char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found %u values", found); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } break; } case TIFF_SHORT: { uint16 * valp = NULL; uint32 found=0; ret =TIFFGetFieldSHORT(ctif, tag, &valp, &found); if (ret.returncode != is_valid) return ret; if (1 == found) { uint16 val = *valp; if ((val >= a && val <= b )) { ret.returncode=is_valid; free( valp); return ret; } else { free( valp); char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found value %u", val); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } } else { if (NULL != valp) { free(valp); valp=NULL; } char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found %u values", found); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } break; } case TIFF_RATIONAL: { float * valp = NULL; uint32 found=0; ret=TIFFGetFieldRATIONAL(ctif, tag, &valp, &found); if (ret.returncode != is_valid) return ret; if (1 == found) { float val = *valp; if ((val >= a && val <= b )) { ret.returncode=is_valid; free( valp); return ret; } else { free( valp); char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found value %f", val); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } } else { if (NULL != valp) { free(valp); valp=NULL; } char value[VALUESTRLEN]; snprintf(value, sizeof(value), "found %u values", found); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } break; } default: /* none */ { ret = set_value_found_ret(&ret, TIFFTypeName(datatype)); ret.returncode = tagerror_unexpected_type_found; return ret; } } ret.returncode=should_not_occur; assert( ret.returncode != should_not_occur); return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_value_matching_regex.c000066400000000000000000000111471327425157300257400ustar00rootroot00000000000000#include "check.h" #include "check_helper.h" #include #include /* #define DEBUG */ ret_t check_tag_has_value_matching_regex(ctiff_t * ctif, tag_t tag, const char * regex_string) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; TIFFDataType datatype = TIFFGetRawTagType( ctif, tag ); switch (datatype) { case TIFF_ASCII: { char * val=NULL; uint32 count=0; int r = 0; ret = TIFFGetFieldASCII(ctif, tag, &val, &count); if (ret.returncode != is_valid) return ret; if (0 < count) { for (uint32 i=0; i rc=%d\n", TIFFTagName(tag), count, val, rc); #endif pcre_free( re ); if (rc >= 0 ) { ret.returncode=is_valid; return ret; } else { switch(rc) { case PCRE_ERROR_NOMATCH: ret = set_value_found_ret(&ret, val); free(val); ret.returncode = tagerror_pcre_nomatch; return ret; break; /* Handle other special cases if you like */ } } } else { char array[VALUESTRLEN]; snprintf(array, sizeof(array), "regex '%s' compile error: %s at offset: %i\n",regex_string, errorcode, erroffset); ret = set_value_found_ret(&ret, array); ret.returncode = pcre_compile_error; free(val); return ret; } } else { ret.returncode = tagerror_expected_count_iszero; free(val); return ret; } } default: /* none */ { ret = set_value_found_ret( &ret, TIFFTypeName(datatype)); ret.returncode = tagerror_unexpected_type_found; return ret; } } } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_value_quiet.c000066400000000000000000000052111327425157300240760ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #include /* #define DEBUG */ ret_t check_tag_has_value_quiet(ctiff_t * ctif, tag_t tag, unsigned int expected_value) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; ifd_entry_t ifd_entry = TIFFGetRawIFDEntry(ctif, tag); if (ifd_entry.count > 1) { ret = set_value_found_ret(&ret, int2str(ifd_entry.count)); ret.returncode = tagerror_expected_count_isgreaterone; return ret; } switch (ifd_entry.datatype) { case TIFF_LONG: { if (expected_value != ifd_entry.data32) { ret = set_value_found_ret(&ret, int2str(ifd_entry.data32)); ret.returncode = tagerror_value_differs; return ret; } break; } case TIFF_SHORT: { if (expected_value != ifd_entry.data16[0]) { ret = set_value_found_ret(&ret, int2str(ifd_entry.data16[0])); ret.returncode = tagerror_value_differs; return ret; } break; } case TIFF_RATIONAL: { if (0 == ifd_entry.data16[1]) { char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "%i/%i", ifd_entry.data16[0], ifd_entry.data16[1]); ret = set_value_found_ret(&ret, msg); ret.returncode = tagerror_denominator_is_zero_in_fract; return ret; } else if (expected_value - (ifd_entry.data16[0] / ifd_entry.data16[1]) > 1) { ret = set_value_found_ret(&ret, frac2str( ifd_entry.data16[0], ifd_entry.data16[1])); ret.returncode = tagerror_value_differs; return ret; } break; }; default: { /* none */ ret = set_value_found_ret(&ret, TIFFTypeName(ifd_entry.datatype)); ret.returncode = tagerror_unexpected_type_found; return ret; /* break; */ }; }; ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_has_valuelist.c000066400000000000000000000121241327425157300235640ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" #include #include /* #define DEBUG */ ret_t check_tag_has_valuelist(ctiff_t * ctif, tag_t tag, int count, const unsigned int * values) { GET_EMPTY_RET(ret) tifp_check( ctif); ret=check_tag_quiet(ctif, tag); if (ret.returncode != is_valid) return ret; if (count < 0) { if (snprintf(ret.value_found, VALUESTRLEN, "count=%i", count) > 0) { ret.returncode = calling_error_count_size; return ret; } else { ret.returncode = could_not_print; return ret; } } unsigned int v[count]; for (int i=0; i< count; i++) { v[i] = *values; values++; } char value[VALUESTRLEN]; memset(value, '\0', VALUESTRLEN); ifd_entry_t ifd_entry = TIFFGetRawIFDEntry(ctif, tag); if ((uint32) count != ifd_entry.count) { snprintf(value, sizeof(value), "has %u values", ifd_entry.count); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_expected_count_differs; return ret; } switch (ifd_entry.datatype) { case TIFF_LONG: { /* value */ if (ifd_entry.value_or_offset == is_value) { for (int i=0; i< count; i++) { if (v[i] != ifd_entry.data32) { snprintf(value, sizeof(value), "at [%i]=%u", i, ifd_entry.data32); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } } } /* offset */ if (ifd_entry.value_or_offset == is_offset) { offset_t offset; ret = read_offsetdata(ctif, ifd_entry.data32offset, count, ifd_entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { return ret; } uint32 * p = offset.data32p; for (int i=0; i< count; i++) { uint32 pval = *p; #ifdef DEBUG printf("OFFSET: v[%i]=%u p[%i]=%u\n", i,v[i],i,pval); #endif if (v[i] != *p) { snprintf(value, sizeof(value), "at [%i]=%u", i, pval); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } p++; } } break; } case TIFF_SHORT: { /* value */ if (ifd_entry.value_or_offset == is_value) { for (int i=0; i< count; i++) { int c = (v[i]) == (ifd_entry.data16[i]); if (!c) { snprintf(value, sizeof(value), "at [%i]=%u", i, ifd_entry.data16[i]); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } } } /* offset */ if (ifd_entry.value_or_offset == is_offset) { offset_t offset; ret = read_offsetdata(ctif, ifd_entry.data32offset, count, ifd_entry.datatype, &offset, &ret); if (ret.returncode != is_valid) { return ret; } uint16 * p = offset.data16p; for (int i=0; i< count; i++) { uint16 pval = *p; #ifdef DEBUG printf("SHORTOFFSET (tag=%i): v[%i]=%u p[%i]=0x%04x\n", tag, i,v[i],i,pval); #endif if (v[i] != pval) { snprintf(value, sizeof(value), "at [%i]=%u", i, pval); ret = set_value_found_ret (&ret, value); ret.returncode = tagerror_value_differs; return ret; } p++; } } break; } default: /* none */ { snprintf(value, sizeof(value), "type:%s", TIFFTypeName(ifd_entry.datatype)); ret = set_value_found_ret(&ret, value); ret.returncode = tagerror_unexpected_type_found; return ret; } } ret.returncode=is_valid; return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/tagrules/check_tag_quiet.c000066400000000000000000000013471327425157300220550ustar00rootroot00000000000000/* rule based checks if given TIFF is a specific baseline TIFF * * author: Andreas Romeyke, 2015 * licensed under conditions of libtiff * (see http://libtiff.maptools.org/misc.html) * */ #include "check.h" #include "check_helper.h" /* #define DEBUG */ /* checks if TIF has a specified tag */ ret_t check_tag_quiet(ctiff_t * ctif, tag_t tag) { GET_EMPTY_RET(ret) tifp_check( ctif); if (-1 < TIFFGetRawTagListIndex(ctif, tag)) { ret.returncode=is_valid; } else { char msg[VALUESTRLEN]; snprintf(msg, VALUESTRLEN, "tag %i is missing", tag); ret = set_value_found_ret(&ret, msg); ret.returncode=tag_does_not_exist; } return ret; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/toolchain-32bit_on64.cmake000066400000000000000000000006271327425157300215150ustar00rootroot00000000000000set (CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_SYSTEM_PROCESSOR "i686") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32" CACHE STRING "c++ flags") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32" CACHE STRING "c flags") set (CMAKE_FIND_ROOT_PATH /usr/lib32) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) checkit_tiff-0.4.2/src/toolchain-mingw32.cmake000066400000000000000000000006001327425157300212010ustar00rootroot00000000000000set (CMAKE_SYSTEM_NAME Windows) set (CMAKE_C_COMPILER i686-w64-mingw32-gcc) set (CMAKE_CXX_COMPILER i686-w64-mingw32-g++) set (CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # call cmake: # cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-mingw32.cmake SRCPATH checkit_tiff-0.4.2/src/toolchain-mingw64.cmake000066400000000000000000000006071327425157300212150ustar00rootroot00000000000000set (CMAKE_SYSTEM_NAME Windows) set (CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) set (CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) set (CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/) set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # call cmake: # cmake -DCMAKE_TOOLCHAIN_FILE=toolchain-mingw64.cmake SRCPATH checkit_tiff-0.4.2/src/validate_icc/000077500000000000000000000000001327425157300173465ustar00rootroot00000000000000checkit_tiff-0.4.2/src/validate_icc/check_icc_header.c000066400000000000000000000312001327425157300227110ustar00rootroot00000000000000/* checks ICC Profile, using Spec http://www.color.org/specification/ICC1v43_2010-12.pdf */ #include "validate_icc.h" /* #define USE_WARNING #ifdef USE_WARNING #define FAIL(...) {fprintf(stderr, __VA_ARGS__); return 1;}; #define INFO(...) fprintf(stderr,__VA_ARGS__); #else #define FAIL(...) {return 1;}; #define INFO(...) ; #endif */ #define FAIL(RETCODE, ...) {snprintf(errmessage, errsize, __VA_ARGS__); return RETCODE;}; #define INFO(...) ; //#define INFO(...) fprintf(stderr,__VA_ARGS__); // TODO: errormessage pointer und maxsize übergeben /* parses common parts of ICC 2.4.0 / 4.3.0 and 5.0.0 (ICC MAX) headers */ icc_returncode_t parse_icc_common_header(unsigned long iccsize, char * iccdata, unsigned long errsize, char * errmessage, icc_profile_version_t icc_profile_version) { assert(iccdata != NULL); assert(errmessage != NULL); assert(errsize > 0); if (iccsize < 128) FAIL(icc_error_header_generic, "iccsize=%lu", iccsize); unsigned long profilesize = ( ((iccdata[0] & 0x00ff) <<24) | ((iccdata[1] & 0x00ff) <<16) | ((iccdata[2] & 0x00ff) <<8) | (iccdata[3] & 0x00ff) ) & 0xffffffff; INFO("ICC: profilesize=%li %0x\n", profilesize, profilesize); if (profilesize != iccsize) FAIL(icc_error_committed_size_differs, "committed ICC size (%lu / 0x%04lx) differs from encoded profilesize (%lu / 0x%04lx)", iccsize, iccsize, profilesize, profilesize); /* -- */ char preferredcmmtype[5]=" "; memcpy(preferredcmmtype, &iccdata[4],4); INFO("ICC: preferredcmmtype='%s'\n", preferredcmmtype); /* TODO: check if this is really correct, because found some TIFFs with * value 'Lino', handle with care! */ if ( /* see document http://www.color.org/registry/signature/TagRegistry-2016-05.pdf */ ('\0' != preferredcmmtype[0]) && (0 != strncmp("ADBE", preferredcmmtype, 4)) && (0 != strncmp("ACMS", preferredcmmtype, 4)) && (0 != strncmp("appl", preferredcmmtype, 4)) && (0 != strncmp("CCMS", preferredcmmtype, 4)) && (0 != strncmp("UCCM", preferredcmmtype, 4)) && (0 != strncmp("UCMS", preferredcmmtype, 4)) && (0 != strncmp("EFI ", preferredcmmtype, 4)) && (0 != strncmp("FF ", preferredcmmtype, 4)) && (0 != strncmp("EXAC", preferredcmmtype, 4)) && (0 != strncmp("HCMM", preferredcmmtype, 4)) && (0 != strncmp("argl", preferredcmmtype, 4)) && (0 != strncmp("LgoS", preferredcmmtype, 4)) && (0 != strncmp("HDM ", preferredcmmtype, 4)) && (0 != strncmp("lcms", preferredcmmtype, 4)) && (0 != strncmp("KCMS", preferredcmmtype, 4)) && (0 != strncmp("MCML", preferredcmmtype, 4)) && (0 != strncmp("WCS ", preferredcmmtype, 4)) && (0 != strncmp("SIGN", preferredcmmtype, 4)) && (0 != strncmp("RGMS", preferredcmmtype, 4)) && (0 != strncmp("SICC", preferredcmmtype, 4)) && (0 != strncmp("TCMM", preferredcmmtype, 4)) && (0 != strncmp("32BT", preferredcmmtype, 4)) && (0 != strncmp("WTG ", preferredcmmtype, 4)) && #ifdef ALLOW_CMMTYPE_LINO (0 != strncmp("LINO", preferredcmmtype, 4)) && #endif (0 != strncmp("zc00", preferredcmmtype, 4)) ) FAIL(icc_error_preferredcmmtype, "preferred cmmtype ('%s') should be empty or (possibly, because ICC validation is alpha code) one of following strings: 'ADBE' 'ACMS' 'appl' 'CCMS' 'UCCM' 'UCMS' 'EFI ' 'FF ' 'EXAC' 'HCMM' 'argl' 'LgoS' 'HDM ' 'lcms' 'KCMS' 'MCML' 'WCS ' 'SIGN' 'RGMS' 'SICC' 'TCMM' '32BT' 'WTG ' 'zc00'", preferredcmmtype); /* -- */ char profileversion[6]=" "; snprintf(profileversion, 6, "%i.%i.%i", (iccdata[8]) & 0x000f, ((iccdata[9] & 0x00f0) >>4), (iccdata[9] & 0x000f)); INFO("ICC: profileversion='%s'\n", profileversion); // TODO: 2.4.0 or 4.3.0, others not allowed? /* -- */ char profileclass[5]=" "; memcpy(profileclass, &iccdata[12],4); INFO("ICC: profileclass='%s'\n", profileclass); if ( /* see page 13, table 11 of http://www.color.org/ICC_Minor_Revision_for_Web.pdf */ (0 != strncmp("scnr", profileclass, 4)) && (0 != strncmp("mntr", profileclass, 4)) && (0 != strncmp("prtr", profileclass, 4)) && (0 != strncmp("link", profileclass, 4)) && (0 != strncmp("spac", profileclass, 4)) && (0 != strncmp("abst", profileclass, 4)) && (0 != strncmp("nmcl", profileclass, 4)) ) FAIL(icc_error_profileclass, "profile class ('%s'), should be one of following strings for device classes: 'scnr', 'mntr', 'prtr' or for profile classes: 'link', 'spac', 'abst', 'nmcl'", profileclass); /* -- */ char colorspacedata[5]=" "; memcpy(colorspacedata, &iccdata[16],4); INFO("ICC: colorspacedata='%s'\n", colorspacedata); if ( /* see page 14, table 13 of http://www.color.org/ICC_Minor_Revision_for_Web.pdf */ (0 != strncmp("XYZ ", colorspacedata, 4)) && (0 != strncmp("Lab ", colorspacedata, 4)) && (0 != strncmp("Luv ", colorspacedata, 4)) && (0 != strncmp("YCbr", colorspacedata, 4)) && (0 != strncmp("Yvx ", colorspacedata, 4)) && (0 != strncmp("RGB ", colorspacedata, 4)) && (0 != strncmp("GRAY", colorspacedata, 4)) && (0 != strncmp("HSV ", colorspacedata, 4)) && (0 != strncmp("HLS ", colorspacedata, 4)) && (0 != strncmp("CMYK", colorspacedata, 4)) && (0 != strncmp("CMY ", colorspacedata, 4)) && (0 != strncmp("2CLR", colorspacedata, 4)) && (0 != strncmp("3CLR", colorspacedata, 4)) && (0 != strncmp("4CLR", colorspacedata, 4)) && (0 != strncmp("5CLR", colorspacedata, 4)) && (0 != strncmp("6CLR", colorspacedata, 4)) && (0 != strncmp("7CLR", colorspacedata, 4)) && (0 != strncmp("8CLR", colorspacedata, 4)) && (0 != strncmp("9CLR", colorspacedata, 4)) && (0 != strncmp("ACLR", colorspacedata, 4)) && (0 != strncmp("BCLR", colorspacedata, 4)) && (0 != strncmp("CCLR", colorspacedata, 4)) && (0 != strncmp("DCLR", colorspacedata, 4)) && (0 != strncmp("ECLR", colorspacedata, 4)) && (0 != strncmp("FCLR", colorspacedata, 4)) ) FAIL(icc_error_colorspacedata, "colorspace data ('%s'), should be one of following strings: 'XYZ ' 'Lab ' 'Luv ' 'YCbr' 'Yvx ' 'RGB ' 'GRAY' 'HSV ' 'HLS ' 'CMYK' 'CMY ' '2CLR' '3CLR' '4CLR' '5CLR' '6CLR' '7CLR' '8CLR' '9CLR' 'ACLR' 'BCLR' 'CCLR' 'DCLR' 'ECLR' 'FCLR'", colorspacedata); /* -- */ char connectionspacedata[5]=" "; memcpy(connectionspacedata, &iccdata[20],4); INFO("ICC: connectionspacedata(PCS)='%s'\n", connectionspacedata); if ( /* see page 15, table 14 of http://www.color.org/ICC_Minor_Revision_for_Web.pdf */ (0 != strncmp("XYZ ", connectionspacedata, 4)) && (0 != strncmp("Lab ", connectionspacedata, 4)) ) FAIL(icc_error_connectionspacedata, "connection space data ('%s') should be one of following strings: 'XYZ ' 'Lab '", connectionspacedata); /* -- */ // datetime 24-35 char datetime[20]; snprintf(datetime, 20, "%.4d:%.2d:%.2d %.2d:%.2d:%.2d", ((iccdata[24] & 0x00ff)<<8 | (iccdata[25] & 0x00ff)), // yyyy ((iccdata[26] & 0x00ff)<<8 | (iccdata[27] & 0x00ff)), // MM ((iccdata[28] & 0x00ff)<<8 | (iccdata[29] & 0x00ff)), // DD ((iccdata[30] & 0x00ff)<<8 | (iccdata[31] & 0x00ff)), // hh ((iccdata[32] & 0x00ff)<<8 | (iccdata[33] & 0x00ff)), // mm ((iccdata[34] & 0x00ff)<<8 | (iccdata[35] & 0x00ff)) // ss ); INFO("ICC: datetime='%s'\n", datetime); /* -- */ char profilefilesignature[5]=" "; memcpy(profilefilesignature, &iccdata[36],4); INFO("ICC: profilefilesignature='%s'\n", profilefilesignature); /* -- */ char primaryplattformsignature[5]=" "; memcpy(primaryplattformsignature, &iccdata[40],4); INFO("ICC: primaryplattformsignature='%s'\n", primaryplattformsignature); if ( /* see page 15, table 15 of http://www.color.org/ICC_Minor_Revision_for_Web.pdf */ ('\0' != primaryplattformsignature[0]) && (0 != strncmp("APPL", primaryplattformsignature, 4)) && (0 != strncmp("MSFT", primaryplattformsignature, 4)) && (0 != strncmp("SGI ", primaryplattformsignature, 4)) && (0 != strncmp("SUNW", primaryplattformsignature, 4)) && ((icc_profile_version == icc_profile_v240_v430) && (0 != strncmp("TGNT", primaryplattformsignature, 4))) ) FAIL(icc_error_primaryplatformsignature, "primary plattform signature ('%s') should be empty or one of following strings: 'APPL', 'MSFT', 'SGI ', 'SUNW' (and for v2.x.x only: additional 'TGNT')", primaryplattformsignature); /* -- */ // Profile Flags 44-47 /* -- */ char devicemanufacturer[5]=" "; memcpy(devicemanufacturer, &iccdata[48],4); INFO("ICC: devicemanufacturer='%s'\n", devicemanufacturer); /* -- */ char devicemodel[5]=" "; memcpy(devicemodel, &iccdata[52],4); INFO("ICC: devicemodel='%s'\n", devicemodel); /* -- */ // device attributes 56-63 /* -- */ // rendering intent field 64-67 /* -- */ return icc_is_valid; } /* checks a ICC header for ICC.1:2004-08, see chapter 6 of http://www.color.org/ICC_Minor_Revision_for_Web.pdf * it also allos older 2.x.x versions, but there is no spec available anymore. * But we have checked 2.2.0 with 2.4.0, there is no difference in ICC profile * header */ icc_returncode_t parse_icc_v240(unsigned long iccsize, char* iccdata, unsigned long errsize, char * errmessage) { assert(iccdata != NULL); assert(errmessage != NULL); assert(errsize > 0); if (iccsize < 128) FAIL (icc_error_header_v240_v430, "Invalid ICC profile ICC.1:2001-04, see http://www.color.org/ICC_Minor_Revision_for_Web.pdf for details"); int ret_header = parse_icc_common_header( iccsize, iccdata, errsize, errmessage, icc_profile_v240_v430); if (icc_is_valid != ret_header) return ret_header; else { // PCS xyz illuminant 68-79 /* -- */ // Profile creator signature 80-83 /* -- */ // Reserved field bytes 84-127 }; return icc_is_valid; } /* checks a ICC header for ICC.1:2010, see chapter 7 of http://www.color.org/specification/ICC1v43_2010-12.pdf */ icc_returncode_t parse_icc_v430(unsigned long iccsize, char* iccdata, unsigned long errsize, char * errmessage) { assert(iccdata != NULL); assert(errmessage != NULL); assert(errsize > 0); if (iccsize < 128) FAIL (icc_error_header_1v43_2010, "Invalid ICC profile 1v43_2010, see http://www.color.org/specification/ICC1v43_2010-12.pdf for details"); icc_returncode_t ret_header = parse_icc_common_header( iccsize, iccdata, errsize, errmessage, icc_profile_1v43_2010); if (icc_is_valid != ret_header) return ret_header; else { // PCS illuminant field 68-79 /* -- */ // Profile creator field 80-83 /* -- */ // Profile ID field 84-99 /* -- */ // Reserved field bytes 100-127 }; return icc_is_valid; } /* checks a ICC header for ICC.2 (ICC MAX), see chapter 7 of http://www.color.org/iccmax/ICC.2-2016-7.pdf */ icc_returncode_t parse_icc_v500(unsigned long iccsize, char* iccdata, unsigned long errsize, char * errmessage) { assert(iccdata != NULL); assert(errmessage != NULL); assert(errsize > 0); if (iccsize < 128) FAIL (icc_error_header_v500_2016, "Invalid ICC profile ICC.2:2016, see http://www.color.org/iccmax/ICC.2-2016-7.pdf for details"); int ret_header = parse_icc_common_header( iccsize, iccdata, errsize, errmessage, icc_profile_v500_2016); if (icc_is_valid != ret_header) return ret_header; else { // PCS xyz illuminant 68-79 /* -- */ // Profile creator signature 80-83 /* -- */ // Profile Id Field 84-99 /* -- */ // Spectral PCS 100-103 /* -- */ // Spectral PCS wavelength range 104-109 /* -- */ // Bi-spectral PCS wavelength range 110-115 /* -- */ // MCS signature 116-119 /* -- */ // Profile/Device Subclass 120-123 /* -- */ // Reserved field bytes 124-127 }; return icc_is_valid; } /* returns 0 if valid, !0 if errorneous */ icc_returncode_t parse_icc(unsigned long iccsize, char* iccdata, unsigned long errsize, char * errmessage) { assert(iccdata != NULL); assert(errmessage != NULL); assert(errsize > 0); if (iccsize < 10) FAIL (icc_error_header_generic, "Invalid ICC profile, size is less 10 bytes"); short a = (iccdata[8]) & 0x000f; short b = ((iccdata[9] & 0x00f0) >>4); short c = (iccdata[9] & 0x000f); char profileversion[6]=" "; snprintf(profileversion, 6, "%1i.%1i.%1i", a, b, c); INFO("ICC: profileversion='%s'\n", profileversion); if (0==strncmp(profileversion, "5.0.0", 5)) return parse_icc_v500(iccsize, iccdata, errsize, errmessage); if (0==strncmp(profileversion, "4.3.0",5)) return parse_icc_v430(iccsize, iccdata, errsize, errmessage); else if (0==strncmp(profileversion, "2.4.0",2)) return parse_icc_v240(iccsize,iccdata, errsize, errmessage); else FAIL (icc_error_header_version_outdated, "ICC: profileversion='%s' is outdated or wrong", profileversion); return icc_should_not_occur; } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 smarttab expandtab :*/ checkit_tiff-0.4.2/src/validate_icc/validate_icc.h000066400000000000000000000050571327425157300221350ustar00rootroot00000000000000#include #include #include #define ICC_IS_VALID 0 #define ICC_ERROR_OFFSET 100 typedef enum { icc_profile_1v43_2010, icc_profile_v240_v430, icc_profile_v500_2016, } icc_profile_version_t; typedef enum { icc_is_valid = ICC_IS_VALID, icc_error_profileclass = ICC_ERROR_OFFSET, /* profile class ('%s'), should be one of following strings for device classes: 'scnr', 'mntr', 'prtr' or for profile classes: 'link', 'spac', 'abst', 'nmcl'" */ icc_error_colorspacedata = ICC_ERROR_OFFSET + 1, /* colorspace data ('%s'), should be one of following strings: 'XYZ ' 'Lab ' 'Luv ' 'YCbr' 'Yvx ' 'RGB ' 'GRAY' 'HSV ' 'HLS ' 'CMYK' 'CMY ' '2CLR' '3CLR' '4CLR' '5CLR' '6CLR' '7CLR' '8CLR' '9CLR' 'ACLR' 'BCLR' 'CCLR' 'DCLR' 'ECLR' 'FCLR'" */ icc_error_connectionspacedata = ICC_ERROR_OFFSET + 2, /* "connection space data ('%s') should be one of following strings: 'XYZ ' 'Lab '" */ icc_error_primaryplatformsignature = ICC_ERROR_OFFSET + 3, /* primary plattform signature ('%s') should be empty or one of following strings: 'APPL', 'MSFT', 'SGI ', 'SUNW', 'TGNT' */ icc_error_header_1v43_2010 = ICC_ERROR_OFFSET + 4, /* Invalid ICC profile 1v43_2010, see http://www.color.org/specification/ICC1v43_2010-12.pdf for details */ icc_error_header_v240_v430 = ICC_ERROR_OFFSET + 5, /* Invalid ICC profile ICC.1:2001-04, see http://www.color.org/ICC_Minor_Revision_for_Web.pdf for details */ icc_error_header_generic = ICC_ERROR_OFFSET + 6, /* size < 10 */ icc_error_preferredcmmtype = ICC_ERROR_OFFSET + 7, /* preferred cmmtype ('%s') should be empty or (possibly, because ICC validation is alpha code) one of following strings: 'ADBE' 'ACMS' 'appl' 'CCMS' 'UCCM' 'UCMS' 'EFI ' 'FF ' 'EXAC' 'HCMM' 'argl' 'LgoS' 'HDM ' 'lcms' 'KCMS' 'MCML' 'WCS ' 'SIGN' 'RGMS' 'SICC' 'TCMM' '32BT' 'WTG ' 'zc00'" */ icc_error_committed_size_differs = ICC_ERROR_OFFSET + 8, /* committed ICC size differs from encoded profilesize */ icc_error_header_v500_2016 = ICC_ERROR_OFFSET + 9, /* Invalid ICC profile ICC.1:2001-04, see http://www.color.org/iccmax/ICC.2-2016-7.pdf for details */ icc_error_header_version_undefined = ICC_ERROR_OFFSET +10, /* if header version was undefined yet */ icc_error_header_version_outdated = ICC_ERROR_OFFSET +11, /* if header version was outdated */ icc_should_not_occur = ICC_ERROR_OFFSET +99, } icc_returncode_t; icc_returncode_t parse_icc(unsigned long iccsize, char* iccdata, unsigned long errsize, char * errorneous_value); checkit_tiff-0.4.2/src/version.mk000066400000000000000000000015161327425157300167600ustar00rootroot00000000000000# # source from Ralph Williamsen, # see http://stackoverflow.com/questions/4120001/what-is-the-git-equivalent-for-revision-number # # Set the source control revision similar to subversion to use in 'c' # files as a define. # You must build in the master branch otherwise the build branch will # be prepended to the revision and/or "dirty" appended. This is to # clearly ID developer builds. REPO_REVISION_:=$(shell git rev-list HEAD --count) BUILD_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD) BUILD_REV_ID:=$(shell git rev-parse HEAD) BUILD_REV_ID_SHORT:=$(shell git describe --long --tags --dirty --always) ifeq ($(BUILD_BRANCH), master) REPO_REVISION:=$(REPO_REVISION_)_g$(BUILD_REV_ID_SHORT) else REPO_REVISION:=$(BUILD_BRANCH)_$(REPO_REVISION_)_r$(BUILD_REV_ID_SHORT) endif export REPO_REVISION export BUILD_BRANCH export BUILD_REV_ID checkit_tiff-0.4.2/t/000077500000000000000000000000001327425157300144135ustar00rootroot00000000000000checkit_tiff-0.4.2/t/Testcall.pm000066400000000000000000000055331327425157300165320ustar00rootroot00000000000000use strict; use warnings; package Testcall; use IPC::Open3; use File::Spec; use Exporter 'import'; our @EXPORT = qw( $testdir call_checkit_tiff call_checkit_check_config call2_checkit_check_config prepare cleanup ); my $testdir = "./testdir/"; my $checkit_check_config="../build/checkit_check_config"; my $checkit_tiff="../build/checkit_tiff"; sub call_checkit_tiff { my $cfg=shift; my $tiff = shift; # print "DEBUG: $checkit_tiff -q -c $cfg $tiff\n"; #print "------------------------\n"; #system("$checkit_tiff", "-q", $cfg, $tiff); #print "========================\n"; # code from perlfaq8 my $in = ''; use IO::File; local *CATCHERR = IO::File->new_tmpfile; my $pid = open3($in, \*CATCHOUT, ">&CATCHERR", "$checkit_tiff -q $cfg $tiff"); my @out; my @err; while( ) { push @out, $_; } waitpid($pid, 0); seek CATCHERR, 0, 0; while( ) { push @err, $_; } # my $ret=0; if ($? == -1) { die "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; return $?; } else { $ret=$?>>8; #printf "child exited with value %d\n", $ret; if ($ret != 0) { print "----------->\n"; print join ("\n", @out); use Data::Printer; p( @err ); print "<-----------\n\n"; } } return ($ret == 0) } sub call_checkit_check_config { my $grammar = shift; open(my $FOO, "|$checkit_check_config >/dev/null") or die "check failed: $!\n"; print $FOO $grammar; close $FOO; #print "test '$?'\n"; my $ret=0; if ($? == -1) { die "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; return $?; } else { $ret=$?>>8; #printf "child exited with value %d\n", $? >> 8; } return ($ret == 0) } sub call2_checkit_check_config { my $grammar = shift; my @out; my @tmp; my ($rh, $wh, $eh); use Symbol 'gensym'; $eh = gensym; my $pid = open3($wh, $rh, $eh, "$checkit_check_config"); print $wh $grammar; close $wh; while (<$rh>) { push @out, $_; } while (<$eh>) { push @tmp, $_; } waitpid($pid, 0); if ($? == -1) { die "failed to execute: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; return $?; } else { #printf "child exited with value %d\n", $? >> 8; } return join("", @out, @tmp); } sub prepare { mkdir "$testdir"; return $testdir; } sub cleanup { rmdir "$testdir"; } 1; checkit_tiff-0.4.2/t/compare_stable_with_current_checkit_tiff.sh000066400000000000000000000024071327425157300252310ustar00rootroot00000000000000#!/bin/bash # call with: # compare_stable_with_current_checkit_tiff.sh stable_checkit_tiff stable_cfg current_checkit_tiff current_cfg tiff-dir/ # example: # bash checkit_tiff/t/compare_stable_with_current_checkit_tiff.sh checkit_tiff__stable/build/checkit_tiff checkit_tiff__stable/example_configs/cit_tiff6_baseline_SLUB.cfg checkit_tiff/build/checkit_tiff checkit_tiff/example_configs/cit_tiff6_baseline_SLUB.cfg checkit_tiff/tiffs_should_pass/ STABLE=$1 CONFIGSTABLE=$2 UNSTABLE=$3 CONFIGUNSTABLE=$4 TIFFDIR=$5 echo STABLE =$STABLE CONFIG=$CONFIGSTABLE echo UNSTABLE=$UNSTABLE CONFIG=$CONFIGUNSTABLE echo TIFFDIR=$TIFFDIR # diff -i -w -B -y "$RES_STABLE" "$RES_UNSTABLE" function resultcompare { RES_STABLE=/tmp/res_stable RES_UNSTABLE=/tmp/res_unstable $STABLE "$1" "$CONFIGSTABLE" 2>&1 | fgrep -v "version:" | fgrep -v "licensed under"| sed -e "" > "$RES_STABLE" $UNSTABLE "$CONFIGUNSTABLE" "$1" 2>&1 | fgrep -v "(./)" | fgrep -v "version:" | fgrep -v "licensed under" |sed -e "" > "$RES_UNSTABLE" diff -i -w -B -y "$RES_STABLE" "$RES_UNSTABLE" rm -f $RES_STABLE rm -f $RES_UNSTABLE } IFS=$'\n' for TIFF in $(find $TIFFDIR -name "*.tif*" -print); do echo TIFF=$TIFF echo "-------- DIFF --------" resultcompare $TIFF echo "----------------------" echo done checkit_tiff-0.4.2/t/minimal_256only.tiff000066400000000000000000000000701327425157300202060ustar00rootroot00000000000000II*&checkit_tiff-0.4.2/t/test_config_examples.t000066400000000000000000000010201327425157300207730ustar00rootroot00000000000000#!/usr/bin/perl -w use strict; use warnings; use File::Path; use File::Slurp; use Testcall; use Test::More tests => 6; my $testdir=prepare(); my $cfgdir="../example_configs/"; opendir (my $dirh, $cfgdir) || die "could not open dir '$cfgdir', $!\n"; while(readdir $dirh) { if ($_ !~ /^\./ && $_ =~ /\.cfg$/ && -f "$cfgdir/$_") { my $cfg = "$cfgdir/$_"; my $cfgstring=read_file($cfg); ok ( call_checkit_check_config( $cfgstring), "call (<$cfg)" ); } } cleanup(); checkit_tiff-0.4.2/t/test_grammar.t000066400000000000000000000772031327425157300172760ustar00rootroot00000000000000#!/usr/bin/perl -w use strict; use warnings; use File::Path; use File::Slurp; use Testcall; use Test::More tests => 181; my $testdir=prepare(); ok( call_checkit_check_config('') , "empty grammar"); #ok(!call_checkit_check_config('#') , "empty comment"); ok( call_checkit_check_config("#mode( test )\n") , "single comment (1)"); ok( call_checkit_check_config("# mode( test )\n") , "single comment (2)"); ok( call_checkit_check_config("\n") , "empty grammar with newline only"); ok( call_checkit_check_config("#\n") , "empty comment with newline"); ok( call_checkit_check_config("# mode( test )\n# modal( test )\n") , "double comment"); ok( call_checkit_check_config("mode(baseline)\n") , "mode(baseline)"); #ok(!call_checkit_check_config("mode(extended)\n") , "mode(extended)"); # mode "extended" is not implemented yet #ok(!call_checkit_check_config("mode(nonexist)\n") , "mode(nonexist)"); ok( call_checkit_check_config("mode(enable_type_checks)\n") , "mode(enable_type_checks)"); ok( call_checkit_check_config("mode(enable_offset_checks)\n") , "mode(enable_offset_checks)"); ok( call_checkit_check_config("mode(enable_ifd_checks)\n") , "mode(enable_ifd_checks)"); ok( call_checkit_check_config("256; mandatory; any\n") , "simple tag mandatory any"); ok(!call_checkit_check_config("0; mandatory; any\n") , "simple non-tag mandatory any"); ok( call_checkit_check_config("65535; mandatory; any\n") , "simple 65535 mandatory any"); ok( call_checkit_check_config("2^8; mandatory; any\n") , "simple 2^8 mandatory any"); ok( call_checkit_check_config("256; mandatory; any\n") , "simple tag mandatory any"); ok( call_checkit_check_config("256; mandatory; only(1)\n") , "simple tag mandatory only(1)"); ok( call_checkit_check_config("256; mandatory; ntupel(1,1,1)\n") , "simple tag mandatory ntupel(1,1,1)"); # for supported regexes, see http://www.pcre.org/current/doc/html/pcre2syntax.html ok( call_checkit_check_config("256; mandatory; regex(\"string\")\n") , "simple tag mandatory regex(\"string\")"); ok( call_checkit_check_config("256; mandatory; regex(\"^string\")\n") , "simple tag mandatory regex(\"^string\")"); ok( call_checkit_check_config("256; mandatory; regex(\"string\$\")\n") , "simple tag mandatory regex(\"string\$\")"); ok( call_checkit_check_config("256; mandatory; regex(\"^string\$\")\n") , "simple tag mandatory regex(\"^string\$\")"); ok( call_checkit_check_config("256; mandatory; regex(\"s*\")\n") , "simple tag mandatory regex(\"s*\")"); ok( call_checkit_check_config("256; mandatory; regex(\"s?\")\n") , "simple tag mandatory regex(\"s?\")"); ok( call_checkit_check_config("256; mandatory; regex(\"s+\")\n") , "simple tag mandatory regex(\"s+\")"); ok( call_checkit_check_config("256; mandatory; regex(\"[A-Z]\")\n") , "simple tag mandatory regex(\"[A-Z]\")"); ok( call_checkit_check_config("256; mandatory; regex(\"[^A-Z]\")\n") , "simple tag mandatory regex(\"[^A-Z]\")"); ok( call_checkit_check_config("256; mandatory; range(1,100)\n") , "simple tag mandatory range(1,100)"); ok( call_checkit_check_config("256; mandatory; range(100,1)\n") , "simple tag mandatory range(100,1)"); ok( call_checkit_check_config("256; mandatory; logical_or(100,1)\n") , "simple tag mandatory logical_or(100,1)"); ok( call_checkit_check_config("256; mandatory; logical_or(1,100)\n") , "simple tag mandatory logical_or(1,100)"); ok( call_checkit_check_config("256; mandatory; logical_or(only(100),only(1))\n") , "simple tag mandatory logical_or(only(100),only(1))"); ok( call_checkit_check_config("256; mandatory; logical_or(only(1),only(100))\n") , "simple tag mandatory logical_or(only(1),only(100))"); ok( call_checkit_check_config("256; mandatory; logical_or(ntupel(1,1,1),1)\n") , "simple tag mandatory logical_or(ntupel(1,1,1),1)"); ok( call_checkit_check_config("256; mandatory; logical_or(ntupel(1,1,1),1,regex(\"string\"))\n") , "simple tag mandatory logical_or(ntupel(1,1,1),1,regex(\"string\"))"); ok( call_checkit_check_config("256; mandatory; logical_or(ntupel(8,8,8),ntupel(16,16,16))\n") , "simple tag mandatory logical_or(ntupel(8,8,8),ntupel(16,16,16))"); ok( call_checkit_check_config("315; mandatory; printascii\n") , "simple tag mandatory printascii"); ok( call_checkit_check_config("306; mandatory; datetime\n") , "simple tag mandatory datetime"); ok( call_checkit_check_config("34675; mandatory; iccprofile\n") , "simple tag mandatory iccprofile"); # ok( call_checkit_check_config("256; optional; any\n") , "simple tag optional any"); ok(!call_checkit_check_config("0; optional; any\n") , "simple non-tag optional any"); ok( call_checkit_check_config("256; optional; any\n") , "simple tag optional any"); ok( call_checkit_check_config("256; optional; only(1)\n") , "simple tag optional only(1)"); ok( call_checkit_check_config("256; optional; ntupel(1,1,1)\n") , "simple tag optional ntupel(1,1,1)"); ok( call_checkit_check_config("256; optional; regex(\"string\")\n") , "simple tag optional regex(\"string\")"); ok( call_checkit_check_config("256; optional; range(1,100)\n") , "simple tag optional range(1,100)"); ok( call_checkit_check_config("256; optional; range(100,1)\n") , "simple tag optional range(100,1)"); ok( call_checkit_check_config("256; optional; logical_or(100,1)\n") , "simple tag optional logical_or(100,1)"); ok( call_checkit_check_config("256; optional; logical_or(1,100)\n") , "simple tag optional logical_or(1,100)"); ok( call_checkit_check_config("256; optional; logical_or(only(100),only(1))\n") , "simple tag optional logical_or(only(100,1))"); ok( call_checkit_check_config("256; optional; logical_or(only(1),only(100))\n") , "simple tag optional logical_or(only(1,100))"); ok( call_checkit_check_config("315; optional; printascii\n") , "simple tag optional printascii"); ok( call_checkit_check_config("306; optional; datetime\n") , "simple tag optional datetime"); ok( call_checkit_check_config("34675; optional; iccprofile\n") , "simple tag optional iccprofile"); # ok( call_checkit_check_config("256; depends(255.1); any\n") , "simple tag depends(255.1) any"); ok(!call_checkit_check_config("0; depends(255.1); any\n") , "simple non-tag depends(255.1) any"); ok( call_checkit_check_config("256; depends(255.1); any\n") , "simple tag depends(255.1) any"); ok( call_checkit_check_config("256; depends(255.1); only(1)\n") , "simple tag depends(255.1) only(1)"); ok( call_checkit_check_config("256; depends(255.1); ntupel(1,1,1)\n") , "simple tag depends(255.1) ntupel(1,1,1)"); ok( call_checkit_check_config("256; depends(255.1); regex(\"string\")\n") , "simple tag depends(255.1) regex(\"string\")"); ok( call_checkit_check_config("256; depends(255.1); range(1,100)\n") , "simple tag depends(255.1) range(1,100)"); ok( call_checkit_check_config("256; depends(255.1); range(100,1)\n") , "simple tag depends(255.1) range(100,1)"); ok( call_checkit_check_config("256; depends(255.1); logical_or(100,1)\n") , "simple tag depends(255.1) logical_or(100,1)"); ok( call_checkit_check_config("256; depends(255.1); logical_or(1,100)\n") , "simple tag depends(255.1) logical_or(1,100)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); any\n") , "simple tag depends(255.regex(\"test\")) any"); #ok(!call_checkit_check_config("256; depends(255.printascii); any\n") , "simple tag depends(255.printascii) any, should fail"); #ok(!call_checkit_check_config("256; depends(255.datetime); any\n") , "simple tag depends(255.datetime) any, should fail"); #ok(!call_checkit_check_config("256; depends(255.iccprofile); any\n") , "simple tag depends(255.iccprofile) any, should fail"); ok(!call_checkit_check_config("0; depends(255.regex(\"test\")); any\n") , "simple non-tag depends(255.regex(\"test\")) any"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); any\n") , "simple tag depends(255.regex(\"test\")) any"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); only(1)\n") , "simple tag depends(255.regex(\"test\")) only(1)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); ntupel(1,1,1)\n") , "simple tag depends(255.regex(\"test\")) ntupel(1,1,1)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); regex(\"string\")\n") , "simple tag depends(255.regex(\"test\")) regex(\"string\")"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); range(1,100)\n") , "simple tag depends(255.regex(\"test\")) range(1,100)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); range(100,1)\n") , "simple tag depends(255.regex(\"test\")) range(100,1)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); logical_or(100,1)\n") , "simple tag depends(255.regex(\"test\")) logical_or(100,1)"); ok( call_checkit_check_config("256; depends(255.regex(\"test\")); logical_or(1,100)\n") , "simple tag depends(255.regex(\"test\")) logical_or(1,100)"); ok( call_checkit_check_config("256; depends(255.any); any\n") , "simple tag depends(255.any) any"); ok(!call_checkit_check_config("0; depends(255.any); any\n") , "simple non-tag depends(255.any) any"); ok( call_checkit_check_config("256; depends(255.any); any\n") , "simple tag depends(255.any) any"); ok( call_checkit_check_config("256; depends(255.any); only(1)\n") , "simple tag depends(255.any) only(1)"); ok( call_checkit_check_config("256; depends(255.any); ntupel(1,1,1)\n") , "simple tag depends(255.any) ntupel(1,1,1)"); ok( call_checkit_check_config("256; depends(255.any); regex(\"string\")\n") , "simple tag depends(255.any) regex(\"string\")"); ok( call_checkit_check_config("256; depends(255.any); range(1,100)\n") , "simple tag depends(255.any) range(1,100)"); ok( call_checkit_check_config("256; depends(255.any); range(100,1)\n") , "simple tag depends(255.any) range(100,1)"); ok( call_checkit_check_config("256; depends(255.any); logical_or(100,1)\n") , "simple tag depends(255.any) logical_or(100,1)"); ok( call_checkit_check_config("256; depends(255.any); logical_or(1,100)\n") , "simple tag depends(255.any) logical_or(1,100)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); any\n") , "simple tag depends(255.range(1,100)) any"); ok(!call_checkit_check_config("0; depends(255.range(1,100)); any\n") , "simple non-tag depends(255.range(1,100)) any"); ok( call_checkit_check_config("256; depends(255.range(1,100)); any\n") , "simple tag depends(255.range(1,100)) any"); ok( call_checkit_check_config("256; depends(255.range(1,100)); only(1)\n") , "simple tag depends(255.range(1,100)) only(1)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); ntupel(1,1,1)\n") , "simple tag depends(255.range(1,100)) ntupel(1,1,1)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); regex(\"string\")\n") , "simple tag depends(255.range(1,100)) regex(\"string\")"); ok( call_checkit_check_config("256; depends(255.range(1,100)); range(1,100)\n") , "simple tag depends(255.range(1,100)) range(1,100)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); range(100,1)\n") , "simple tag depends(255.range(1,100)) range(100,1)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); logical_or(100,1)\n") , "simple tag depends(255.range(1,100)) logical_or(100,1)"); ok( call_checkit_check_config("256; depends(255.range(1,100)); logical_or(1,100)\n") , "simple tag depends(255.range(1,100)) logical_or(1,100)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); any\n") , "simple tag depends(255.range(0,1)) any"); ok(!call_checkit_check_config("0; depends(255.range(0,1)); any\n") , "simple non-tag depends(255.range(0,1)) any"); ok( call_checkit_check_config("256; depends(255.range(0,1)); any\n") , "simple tag depends(255.range(0,1)) any"); ok( call_checkit_check_config("256; depends(255.range(0,1)); only(1)\n") , "simple tag depends(255.range(0,1)) only(1)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); ntupel(1,1,1)\n") , "simple tag depends(255.range(0,1)) ntupel(1,1,1)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); regex(\"string\")\n") , "simple tag depends(255.range(0,1)) regex(\"string\")"); ok( call_checkit_check_config("256; depends(255.range(0,1)); range(1,100)\n") , "simple tag depends(255.range(0,1)) range(1,100)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); range(100,1)\n") , "simple tag depends(255.range(0,1)) range(100,1)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); logical_or(100,1)\n") , "simple tag depends(255.range(0,1)) logical_or(100,1)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); logical_or(1,100)\n") , "simple tag depends(255.range(0,1)) logical_or(1,100)"); ok( call_checkit_check_config("256; depends(255.range(0,1)); logical_or(only(100),only(1))\n") , "simple tag depends(255.range(0,1)) logical_or(only(100),only(1)))"); ok( call_checkit_check_config("256; depends(255.range(0,1)); logical_or(only(1),only(100))\n") , "simple tag depends(255.range(0,1)) logical_or(only(1),only(100)))"); ok( call_checkit_check_config("258; depends(262.2); ntupel(8,8,8)\n") , "simple tag depends(262.2); ntupel(8,8,8)"); # ok( call_checkit_check_config("256; optdepends(255.1); any\n") , "simple tag optdepends(255.1) any"); ok(!call_checkit_check_config("0; optdepends(255.1); any\n") , "simple non-tag optdepends(255.1) any"); ok( call_checkit_check_config("256; optdepends(255.1); any\n") , "simple tag optdepends(255.1) any"); ok( call_checkit_check_config("256; optdepends(255.1); only(1)\n") , "simple tag optdepends(255.1) only(1)"); ok( call_checkit_check_config("256; optdepends(255.1); ntupel(1,1,1)\n") , "simple tag optdepends(255.1) ntupel(1,1,1)"); ok( call_checkit_check_config("256; optdepends(255.1); regex(\"string\")\n") , "simple tag optdepends(255.1) regex(\"string\")"); ok( call_checkit_check_config("256; optdepends(255.1); range(1,100)\n") , "simple tag optdepends(255.1) range(1,100)"); ok( call_checkit_check_config("256; optdepends(255.1); range(100,1)\n") , "simple tag optdepends(255.1) range(100,1)"); ok( call_checkit_check_config("256; optdepends(255.1); logical_or(100,1)\n") , "simple tag optdepends(255.1) logical_or(100,1)"); ok( call_checkit_check_config("256; optdepends(255.1); logical_or(1,100)\n") , "simple tag optdepends(255.1) logical_or(1,100)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); any\n") , "simple tag optdepends(255.regex(\"test\")) any"); ok(!call_checkit_check_config("0; optdepends(255.regex(\"test\")); any\n") , "simple non-tag optdepends(255.regex(\"test\")) any"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); any\n") , "simple tag optdepends(255.regex(\"test\")) any"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); only(1)\n") , "simple tag optdepends(255.regex(\"test\")) only(1)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); ntupel(1,1,1)\n") , "simple tag optdepends(255.regex(\"test\")) ntupel(1,1,1)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); regex(\"string\")\n") , "simple tag optdepends(255.regex(\"test\")) regex(\"string\")"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); range(1,100)\n") , "simple tag optdepends(255.regex(\"test\")) range(1,100)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); range(100,1)\n") , "simple tag optdepends(255.regex(\"test\")) range(100,1)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); logical_or(100,1)\n") , "simple tag optdepends(255.regex(\"test\")) logical_or(100,1)"); ok( call_checkit_check_config("256; optdepends(255.regex(\"test\")); logical_or(1,100)\n") , "simple tag optdepends(255.regex(\"test\")) logical_or(1,100)"); ok( call_checkit_check_config("256; optdepends(255.any); any\n") , "simple tag optdepends(255.any) any"); ok(!call_checkit_check_config("0; optdepends(255.any); any\n") , "simple non-tag optdepends(255.any) any"); ok( call_checkit_check_config("256; optdepends(255.any); any\n") , "simple tag optdepends(255.any) any"); ok( call_checkit_check_config("256; optdepends(255.any); only(1)\n") , "simple tag optdepends(255.any) only(1)"); ok( call_checkit_check_config("256; optdepends(255.any); ntupel(1,1,1)\n") , "simple tag optdepends(255.any) ntupel(1,1,1)"); ok( call_checkit_check_config("256; optdepends(255.any); regex(\"string\")\n") , "simple tag optdepends(255.any) regex(\"string\")"); ok( call_checkit_check_config("256; optdepends(255.any); range(1,100)\n") , "simple tag optdepends(255.any) range(1,100)"); ok( call_checkit_check_config("256; optdepends(255.any); range(100,1)\n") , "simple tag optdepends(255.any) range(100,1)"); ok( call_checkit_check_config("256; optdepends(255.any); logical_or(100,1)\n") , "simple tag optdepends(255.any) logical_or(100,1)"); ok( call_checkit_check_config("256; optdepends(255.any); logical_or(1,100)\n") , "simple tag optdepends(255.any) logical_or(1,100)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); any\n") , "simple tag optdepends(255.range(1,100)) any"); ok(!call_checkit_check_config("0; optdepends(255.range(1,100)); any\n") , "simple non-tag optdepends(255.range(1,100)) any"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); any\n") , "simple tag optdepends(255.range(1,100)) any"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); only(1)\n") , "simple tag optdepends(255.range(1,100)) only(1)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); ntupel(1,1,1)\n") , "simple tag optdepends(255.range(1,100)) ntupel(1,1,1)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); regex(\"string\")\n") , "simple tag optdepends(255.range(1,100)) regex(\"string\")"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); range(1,100)\n") , "simple tag optdepends(255.range(1,100)) range(1,100)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); range(100,1)\n") , "simple tag optdepends(255.range(1,100)) range(100,1)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); logical_or(100,1)\n") , "simple tag optdepends(255.range(1,100)) logical_or(100,1)"); ok( call_checkit_check_config("256; optdepends(255.range(1,100)); logical_or(1,100)\n") , "simple tag optdepends(255.range(1,100)) logical_or(1,100)"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); any\n") , "simple tag optdepends(255.range(0,1)) any"); ok(!call_checkit_check_config("0; optdepends(255.range(0,1)); any\n") , "simple non-tag optdepends(255.range(0,1)) any"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); any\n") , "simple tag optdepends(255.range(0,1)) any"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); only(1)\n") , "simple tag optdepends(255.range(0,1)) only(1)"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); ntupel(1,1,1)\n") , "simple tag optdepends(255.range(0,1)) ntupel(1,1,1)"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); regex(\"string\")\n") , "simple tag optdepends(255.range(0,1)) regex(\"string\")"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); range(1,100)\n") , "simple tag optdepends(255.range(0,1)) range(1,100)"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); range(100,1)\n") , "simple tag optdepends(255.range(0,1)) range(100,1)"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); logical_or(only(100),only(1))\n") , "simple tag optdepends(255.range(0,1)) logical_or(only(100),only(1)))"); ok( call_checkit_check_config("256; optdepends(255.range(0,1)); logical_or(only(1),only(100))\n") , "simple tag optdepends(255.range(0,1)) logical_or(only(1),only(100)))"); # my $grammarfile="$testdir/grammar"; my $grammar=<<"GRAMMAR"; 256; mandatory; any GRAMMAR write_file($grammarfile, $grammar); ok( call_checkit_check_config("include($grammarfile)\n"), "include( $grammarfile )"); ok( call_checkit_check_config("256; mandatory; only(2^32)\n") , "simple tag only(2^32)"); ok( call_checkit_check_config("256; mandatory; only(0x0)\n") , "simple tag only(0x0)"); ok( call_checkit_check_config("256; mandatory; only(0x0000)\n") , "simple tag only(0x0000)"); ok( call_checkit_check_config("256; mandatory; only(0xffff)\n") , "simple tag only(0xffff)"); # ### next tests should fail! ok(!call_checkit_check_config("0; mandatory; any\n") , "simple non-tag (0) mandatory any"); ok(!call_checkit_check_config("253; mandatory; any\n") , "simple non-tag (253) mandatory any"); ok(!call_checkit_check_config("65536; mandatory; any\n") , "simple non-tag (65536) mandatory any"); ok(!call_checkit_check_config("2^16; mandatory; any\n") , "simple non-tag (2^16) mandatory any"); #ok(!call_checkit_check_config("0x; mandatory; any\n") , "simple non-tag (0x) mandatory any"); ok(!call_checkit_check_config("0x0; mandatory; any\n") , "simple non-tag (0x0) mandatory any"); #ok(!call_checkit_check_config("0xffx; mandatory; any\n") , "simple non-tag (0xffx) mandatory any"); #ok(!call_checkit_check_config("0xff0x; mandatory; any\n") , "simple non-tag (0xff0x) mandatory any"); #ok(!call_checkit_check_config("0xg; mandatory; any\n") , "simple non-tag (0xg) mandatory any"); ok(!call_checkit_check_config("0x10000; mandatory; any\n") , "simple non-tag (0x10000) mandatory any"); #ok(!call_checkit_check_config("256; mandatory; only(1,1,1)\n") , "simple tag mandatory only(1,1,1)"); #ok(!call_checkit_check_config("256; mandatory; ntupel(\"1\",\"1\",\"1\")\n") , "simple tag mandatory ntupel(\"1\",\"1\",\"1\")"); #ok(!call_checkit_check_config("256, mandatory; any\n") , "simple non-tag (256, mandatory)"); #ok(!call_checkit_check_config("256; mandatory, any\n") , "simple tag (mandatory, any)"); ### next tests checking cornerstones of parser my $expected; #### $expected =<253) at line 1 (error at '0xffffffff01') EXPECT is( call2_checkit_check_config("0xffffffff01; mandatory; only(0xcafe)\n"), $expected, "parsercheck, tag exceeded"); #### $expected =<<'EXPECT'; ((( parse config file ))) wrong tag (should be <65536) at line 1 (error at '65536') EXPECT is( call2_checkit_check_config("65536; mandatory; only(0xcafe)\n"), $expected, "parsercheck, tag exceeded2"); #### $expected =<<'EXPECT'; ((( parse config file ))) wrong tag (should be <65536) at line 1 (error at '0x10000') EXPECT is( call2_checkit_check_config("0x10000; mandatory; only(0xcafe)\n"), $expected, "parsercheck, tag exceeded3"); #### $expected=< 36; use POSIX; my $testdir=prepare(); # testcases should use a cfg, which test only the *special* aspect of broken # tiffs my $checkit_tiff="../build/checkit_tiff"; my $tiffdir="../tiffs_should_fail"; my $cfg_without_modes=< 12; use POSIX; my $testdir=prepare(); my $cfgfile="../example_configs/cit_tiff_baseline_minimal.cfg"; my $tiffdir="../tiffs_should_pass"; my $baselinetiff="$tiffdir/minimal_valid_baseline.tiff"; my $smalltiff="$tiffdir/minimal_valid.tiff"; ok ( call_checkit_tiff( $cfgfile, $baselinetiff), "call ($cfgfile, $baselinetiff), TIFF6 baseline" ); ## all mandatory my $cfg=<.Z\>.iFLH- E#- [*:1l~<&q?,f;|.lJH8ƬnZd6+걿ԔNH=& 2T,dl!jF$Lcl헫p"AѵeaBPo՘P3ޅOw!/Y] ᷯ/l'^(ɍtW"N]z1fEqon1k}(h}tJQr^; yL& Zm-jHbuRXD`9o]]N^.(&fj.@}oJ~<Mɕ֙d)=iJ%ʶtZ˲qnH-wzr hӾʢYs2ezL?~eW{*8MѭBvU^Ȓ go6ʊ{Br8}69ä3t gJ+ӿqf+Ta~+qX=(ѵ8n[h:UIې5 'N~qb\fcjN> Zq?j/#@r(0 Bm!.LR!/m^ws^25}1^NV"@5, bay OǛs8Cj@@UEcC{HakfW1ߞn={lo$ӋSyiC ĵ(&jI KGhOd 7YV|vHnAm0ș63dQӁ.:9*5oN':{[SI!Aj%튾zWއ"25NȝĆ7pb6oHcz$4~\E8m>|?P xƞ4hݑ&s5ZGb,͈{PYp0- /u\bh+t+&\z_nt$¯n LròaZsk~d8 z`Q7.mLx6wp^ڡNGqZ طSRDwg@4EgTfm(&bnk/i(gUA&) 8j8'Tx52Mˏv3MIS[K#,\uku5al/Rȵ<\׸sW;w2tC`KnLt{Z/9l^?>o|Ƃ=a@QDTsúc,\df}+jOm5`2F[^ G@u'"_:w>Wa:+ &4tn$fvi[oаlb WJ *'Ww^L@'4 HJҭ 9OKB^iY%z~8-n\ n; Hj-b|G!2Q5%69Ak)쓁L&a腈O;_Kh`恣$ϭ]dn@p9~*F㺈[Ģ&ŀ[^F]kCCəQ8Jd5l[ }%U{"K.&Nw_1J@{b(gã>}"lN)\kXA{" [q#33ZNEЂ9Ξ&YiIEVkz2"#q:Η' FZn%$#e 5^6ED˅9"F?04 @2 g~9TvD)MYntז)BMVy^}Ѓ"Qm) 0:W)Cx[V$j c!_G}QkzTLJE$rv ʾYty8X6{5xI 7Oy5Ÿ̧2H Cmzj%dGyuHc/8t0WD+wD1tדn fMiraniلW\Di) 5A#,SCZdmfQ/m7m\5=UCрG3g8~5nk9<֛b2ij9fS1Ä{wf^MKtrRK?_`:SIP'' X҂f)ɔZhv+lA1ݍi@zg)́,(-L7!" P\DnD?nҏPĝ:ӑ] ΐ!My 9s90-qšoSJ/CHeޒOU{)hQ9'gE=(ڴ nd~@Tp 8Hr7Nꪨ[LzmaOlX;{7(*=#R2kC C1x]σ;0!7Eׅ+gH"[$ʌyb&@gG$EK89̺g0CY\9|E^v5jJ Qc8|j Kg՜O$Z=X7'B }80Åi~㛽?O1A=^X 5UOm qItrlǏ.'YT{&_*llvXV ul Q)oiE)+t% c}xQ7 ŚohHϭi9,A$4Ք!I儘 fd\X_"Cq7uR Q#oΎKKd]lf(9<>s\K&wq)n@TK$GCnQlnjEBSqk֮2 6={=`<~)Z!Pi-}Pn^PHP4<it^j8"i~Y? ʩV~"4t)y hm+SUəK=P؀Ԟzx8%[<;Ӱ%o glb]r yat8׽ Xc J; 7 ]6i#Z;x?6SfHGFwv[ucl ǚǎ8JY} /wQ\- %;F#g4Yt&b;a4()#._a`:hg1L.w}YLEV `RwF^}N2^Uh MZ$Jڂ,xӐ0Qq5L,|)ĉ2ܹZi2>#+e3uB*/+˗u$޸%jbn?Iؘv%#qA-hҌP= 2H!70.d{ <ۂ $+^[v2(>'܋^oe >zV-IH>*Kaῦk;t8ДVPRmWSS?cܓv>",ĈG)}W=ŃOj'Cn9ofCw|AgRhOLcӒW ]Dz^C\t 19)Ƶ*ܼlWۍH&f{E#mlEܯ|۞TݪaϬTZXSǥIԩJ2Vr>tad%AxCf'zbPrJ^8 z ~p?3lj pBǿܹDU&)F/LCm z֒M_"ažBkCu("+yPٿfFqs 'HjT+sg%p0zbUVey׎<?ۙ6"c*(mqoFOyK 5*]枃hqrecFP I&D&Z| p 7 ؂ rQ3<9/^uӄ$ &^Q*)e'z2G:T0lZo7]MkxȂ( QH5 QvT+p: 0.w|()-kXHW;os2D<qyP'hƙ\ .Oٟ/E2%D/p-c ~Wmw ً&5$to†"&X|+ѥ?^;g Y"RE[hĖ]&4Qȿ9!G4*W,{0{u$!~Lw])}#>Gi9;A@ c3OlD/k'TFyP= L$֑Kl䃀U9ݵ$nbNTAx6Q˼0`֟'zmB\7DDUN'~'v)n\ KDF <{l1gKs\mmy Q?$2vv_ Rߵ,A̷c-wik ]jj[Ċ/69I%b¡S:Rބu UJ*=w\X˧1SىN!1IWfH&ON8SxEDHM|Na²8}$ze"fnEiaenx-(cP{p7d\.{Js9S#{~_]h D䤷/ Ϙ-lg Q3"m`_ D;w,b}QH >? /r&Z sFA]޹N7DFnWU;hUkvM6i]r Lc"*V3Y}gmՆXݢ: 3E<\wJ=S/7`@3:8kוC?;˙a,O4Z8UnSj3^~"lz7ڏ#1Qn]-{ed(X2[fQzQN+1hf `.j?t kTَT0.|Y5Rj?C&ɋ,zw$(^L(9tvju,ͩTn;=N ys@&ڼӛ/0 P@}Qʙ*vzEsdx12[v v ys7,8z,|JI03.,݁YYr;&HeC%,ƻ">ȏBxb P7%0}(VT\jt{Bxdqg2z|{0R(O?&lL̒ h/^A"{͘XzwN1#w܊ɫuV-mAJN 0CChyiqKƁxPkm{ᝊ۽޲방:Yp yPVܭԑl$d67cQ }L.K Lp:b@h Ca(9!4HuV0dC q94yv,Ji/d}~nZE{jUOh|u=AWy-V'A.f9/hMUa4rM+IU=j4Hw_b`H \IH䃍 @2ުP(+^Objj SMEJ9 Cc2Qi=v koJ̑#rxKt ٿ"ڏHc! U$:?_;Mף>kD/ܯ@q;cݎ^ɈAsAA_' Ȕ O9 I|[Hx' &zi6=_}4T{s`U:;X#|~0"'c kEtֹ0<@(T+%OWF = $5ODz@/,u;=(;6-BEةH*B#jT-?6A[{6rINd )fZmawl_ppPuCeH;V)oLݿ=e6YU'q~+ج`0|_YatWBɭ9{ MNtm_3/[ %Me!͗b|-{5S2 }%Ih4}g,Ap{ICt T+aOD"8r6Hj;Y ,!|l( $i&1UI[X L)E'&f|;.j8Z詸Mܣ>fۆ42l3:z <x͡]5r,Kt8z8fxX?xk`e.%m]9n^t%Y5 eo6*{ {dkyMD"g &Ϸ'`,Fzy[!nFv<"jL1?͌f2 K\^_N۬*\[2k'I_l^$P_aŤ<f+/h(,(i-_'VAn`?+(@ %v~o _OC{ڵjyR^Y!_As"..EnIO2FSX*O/V`"?M%L\BuX&4hp;~pW|3&_=Kٷ(aY칚X\`,ߗ |OPr\h-߶j:f'f[PT\YjͻrslX 9Y t # JH\J|$Uu$tP5 ðZǵ7bF6aLyMsG|>i}w\(FDtt;Nc#J8Al>`3(iP`8SiEooK[  0v 9iD ;(.y~Ċ{"6+>}v&B[KT &f~]7WwKi.tvmn1<CO|ċ pꧧb=C"ycr+ ;,71JA/)G?Ķ`,7PnDn1#׽rD`ŠBEѪ.+`m|:A$,aԊӤ91B4Hrc}}Tv%2?;)XbJM_DpmhZ8lPۊ#h_!PVJ N, 2)-L$O: 1;@/M#"7nG4@5XHu\G^S z>Ԯsmgm5,):-fB@ WQBقadv:k0M iF- KM˃څ•=WCni6;ę ۬{^CQ'Li*OXHd6o|_\ =\]| E ;-un w(XE߲ݶ^`wCaou1[>W%u\p)&/?uN|m-_WSGqTh7rW@榉|;B*6(ZA)?M Z(8qcU$#Nٳz].2[P/U18@tmѱ<*?I,NX-M|]ebW&R3xJ%&0V&dDLq-R\&Y݁R;tB1&VN(5P2 `Rշ%tvp!%1yRVAFGф$a5wC?әN ZS&Epw4$|[=M>9˱%g EDpeDy-'˜-:S[g6| Ƕ."v.NI~ZxG|G3+o{ rKʧ0~3u!:q#)Jޔɐ6[#QzTֲ0L`cDcӇ-@o~*z,;t ;%MPzX*`&qXbBQb d)s٩>1TlwlI(#/!9~NCieU2SLf09ڶ4ކ\V`ޠF@X@hI<Y¹ H ~lh)zut.q:WBe&9<)ԴQ48jzn-[Ǡ xK?X+ ~=/1`KϡQXրdٹW#첶U+sں> }WIϋ{g 3FV`4ǝb bZR̫=^olA?&CY[~}Gh,2|h'\r^ݱ\ֻM.0.Ĉ ;;'6)y 6E@kU4AU^b8u0ŝ75- A#A >R1ė\ qMHmWMgJf|.cwd/eRm@2d^9T{FcTF\ys׬I"F9;B]ls٘nehNy'RQ !ŧ1fE߾sؐK&qS)jzGr2Oz4µAg2@wm_I[mÏo= IcNGum7q&ÊR]b:&qpzHQ:334n鳑f152s:Rpb\ =ipPt>8F&oK({Q;rTw ǘ]rQN{տ:BOU0f9 =*rb pfn_csDOyg3p>/ʒiDq$2ȟDZ"X⼨cJ@?12AmVprpQ&x5ŦuNW4{b\PM :66񗔚l2Eky#COd=#gFH3sdY?pI9\b-y=r짠 ~;A c5Pžtw(Ǖi׮B 4,L f^vd@؞I i)wu2X(:ǝ-";$„4xbR&E)Mtfkރ>Gx*o0GSe/ORB5pkS}>Uf{~JISN%1J~-VV5"frG \ pq堜ތ{o/*X:cĆGX-=lQpAlħƮfWf 7A]V>cw_چbXGYL(_O]rn7KBr C̔*&{΅H%de; ;~A aT@KN 6Sjj;ҚKJ fInq)Pͻ{](G-eǮu^jb֮KRb:bw'uW9_%@Z8,6\ aȌCl> eAoيu&n&^$'XbSх^߄+GR.B&# I;9Mgb+{T9#/TL% nR*i󦖇rmFh/oԳgZu~Gzo C(pN:j2{:*kpy7uv'&"tU} Uw94Obք{00Kݠ)F#І-won2;f_)NrWLcY?Tm魳9_B˵D ;t'曠i`:j̇N=ft .[#)d''b8YQ/:A*sw"pqGmГkK8e0nsk1pX[# ;:|<[BnڎF:套:QT,*<[+ڣ ;d1Al[1Q`nargnva*^w۝[6b4Do泥E zH8s8{E\/bDT%ٞ#Px)783z`,z5']TqLlMOD7!.:3'p27~%xvlc-U=VfZRxB}~ mJm~r@aR"\Dx()))JGc7 S񝞈Þ,bv2onYdD2G'iTߤov+ aMJ+Xӳ4մ:)r5XJInVi1j4ؿGqKmtY]Sº}WYQGq,I8uux%3x} UX͛7wO ]8IJ,>+Z!<(<:<:0V5ptjx3Dch Ct^|}Gvoȏ {@ ;׿ /z2Y7aGYurb5^7ۊ$U']08> 2 krIOD0Z<% vS4](rP~"zTtZ8bg}z _MNBVNq5t qGpVT}Cgr>t`IōNdnyFLE=9}~W`ׁo2jL]YÉ7j/F%f&EYqW? +n٫gmo=sr갩'hHBih8ZԮC~V )qr_纙!d-_򡎝mW!H9/˒&f_?'!Q/Z wuNď!rًpknipT4؋^{e0Hכֿ2@4Vֽi;=ƚW 6{[a3|KoEc:$G_A S(E%[Ptܾ%J_o6ؤqRťz5nnԡ{t6+c<( jJn  nW3R\2^O k 5v*MVIP=rU%ؙs(L.}nQuz1xb#яcQ#(5A#b-\@Hg$h2oF *tnr Uڥ{ų'$&(+,8:D K8wM171,'-F DZ,.Y*o$E3ԯYR:z?QN*P c¸/TDJo̶if'ɯƫň `IX\t)T6$hZd5Vcޠd5Zmz[N$M[KďZ[=orE95y'E&Q-oQO ȸԹ:T}U]+&Qx^꭯Wdt"SOtkj2&Xƛ9B$e⛍6Z3EOsjғ99<Z| #PA1;{}Sũ8A?;[@93]SZa>áaҙ3sn"sEv^TQG|.vBȮ'L2W5m}!iSDMޚ~[jX$KhWcf)s5}͵їD9)V:$ (% V;<HgG*kЋ3 l;ܝd5WshLK(Lm#)Xn ƍzJQeq̸`T`2puMDL"'+5-tk'yQ7ZɳCzgٜwƓ!VljL1y]RUTSq5?3J`F#A5O%2뚢JB+ͩ&?!%&*s[_mg%hj{mxe@@?A`Ѣ!M.Q4D¿. 䖥xz 3, ͭ$⬪`.PzXgAo6%{ی 72/ͺo!%˳0D{Ǯft nơ"}0spoCųT],hϵZO%iLjvqLCJCrXp~n/4ND [v2oL_99VX/F$4|}K7  k2SL5~;Ǵ;(:MY")'EL< Nh IeJi/SM)%3RB&i9LCΠ\2փ1H{FόPn)ow J3NAiEbBdSIh<`ݺ.{t4 &Kz{IS0 4^a]}42_Q\(|W'rAzȾt>Wy +,]\@B:OM|Eh{w`g \{N5AO*pDoVD>͎2 sL)о*}hsUG*(,TQ9|Kd'"w%fgA|0F_^wS_ Q: sdhpڳ`!A Jԛ3400f_ D$s @sa-@4bI Ko}ԟ0fM۟g[U%z6gxzo!q2L޻@2mg:<'2׌8:}~MB4nO Xm/8Zsc@5 MN`Og%1Qʷk+Qq)}B.w4woF{<ןqM$ _%ew#P<:\MeY-]AJ|ha_t()0a5h|#m3P=qΕJfcDiei3HpDxcb;B-rTi3nM迖T|,U.֐La@<bMVi1RMޟ /hej *V]4+ާ6H ol‘crM[&kjS;|M 9i ׶+xy"{S<_qJBbo:⳸*<ݖGe@M5BzDO=pq[l$<4~"ڲ/4yoWe~ [hh׃`=\;UB9e#8# L]Jg-J.F{|Ź(V{V'cĭ`)d"X26נ{[k*0)#"!Šd)7A]A.ozlGHg>?oQʟsl~"|zyfv] ia@^S^nUʢ<;Z+WfY"ӲUNW@"&;U|u9 3Qr00Ү~,} [~S۾>}^F"5gNs?ҒbNtug_0g*q9bN?,0JFiG'/A, qtQU=!*FBCCV,ܙ BZ`kT=,IBIݘ[IGjHl>n`$FHYaØ"߬qi%+bwpTb)<ބr:Zڠ5{` |x*fm!m1pIA:.NZ綠'>:DP!gSt\d+ QHtÇe#"H/nZ Բ1Y/'+EhiP Tj۷57G8;%@'. y:Ӏή;PVMTʳuG}x[;n{g((WɿJ\K:Tq0+x-k\;%v[& lGvus*yf uLP Lsusv-+J¹^54ș3f4.$?[}Z> Zz*l5ofj=k+?G7pUt7=H;d}SmI ` ޥNB\!/`V3Jx|ǘ1Uil5&LtG>.W5/.w\v%NJ#>HD >]^s3~%r~19 pڃ{E}6uIN0U%PClF, ,Ua W=ݬ3Vg@b:BRb| LkЖ4߉r@U;h+ c`E+IӊdP]#ZyVNx,m oRx.:&`(4$+QOOI|K92=TYq -_ܶ3e%[_ac<1\}%.q0kʿ쁃*E `\'n~"9 шdS<>SZ 'Y@*:%T^ α=X![ENzv'C\\z pF J](6zt'̏I>яY ={MbiiƟ]|iC$p"E5Uuԟ1̽0H\_7yhEŷ,oy["f=dCfB:;RuЀ-}WAEg)lE_02=x;?Pň_zp۷+:ULwXDcye+l訟x{Brr,€2i-& 8_!]ѵϗFWdipHޭI£cmE-g#L~R,΅@{:C&>ƿ ǹ}4l[˱tP8hAU'k(bi{xVQhm -|q>S@wk Y[R9iM80G!sV2.jWRIx)K{.U ӌm؃R5S\%U污dp?s87'ij,Q;'8)H+*=@@X H6 Vɟ ^zB+8ֵ;Y "Ityijy7{8kCZ_`xv.td gEg<^7H N"JmP3%)\Gh~ib,T`M1 ^}9UK%%ϱFiL!\*o}SAB]T"[U! (z;厔݂('M.>)*~RܯTqLq,m篯`]螡=T\ɵ-8u*{z;e$wyɺܘ\pFGORj&ߧrЄU/;ߐj]u9"w[Y>j\2Wrh-!أ2_8n`Wp&%8 Rj-M1;rq1 gN`F 2~3\?W gnIwV8\:! M ,KJC8BDqppMZq?v̵s<$;>`$Ăo"=@i27j)< JCcDp>FX8RFRR34^z_~uz[6it.2VSPSTm/ @=TT̲ɕuWk~֙Rg't+1 uDܞ[Ԗ>?o^~1H `u;A%Dk/7rp~:9`wUEo,/BM"Y{Ũaa!քQԬ.f b-jmu%%hO%in[X΍v0>՘ +{"Ű#Ip ήpcVV}˙.E`?ޢ z\zӢ2˿G#y#32㘄FU'JޘC{/3ՈxbTDT8$hޥH@;9uʪ }X)}pߡb+J[0JM`jY+FOフF "۳~[: oDu/oQ'5A7p8K1jdS$ {:j E>u%I\ <1'z 6vq$Y/bzHK8cڕR,א)P B *E7j*r12Aw*a]|e%H݈QgODxvn.ə#g Im QBR*EOE:Y7۶IKYZ[mۆl C;k_ݪ}%"yA8z~6Qn꣇j=Ҭ!sHcRHXsg?)PhjH?C"=T"YLџ!|}TOOcD 8:< Ax9tX`,&mzHBvFTDpT1_u9tkW+ZG!߻ ԢD'vx X}C^V;$7Boչ`iT(%.k 8lnVe @O7: EIחriQ<*L9mo^tLѻtb?MAUz6չXry%$:8h =Ώ蒨n<" srM+vNd\UXK6hAJiW ȜߘìO :p/q'uY߶=f5~.;)Dݸԝ\&qmDs1݅ٞ%֚?MM~p̸=ˤSX$ *4 {2)wĢ- ԉT?XB&=!TL1ÁW ^aG 'h lٮDZl3.7 ѩ~}^ TaY/ˆA'dj@LMޯW p]SMԞYb7V,Sulah"⣿G[O21~\~? .!%z!doJ##me1#] rF\j$gnOm]FbgM';z9 V1૩ Te[+A)'lԮцH͌jNAE;!6I$LF?PPxP͔[.!ș;Wp7*n2Qߠ(@!| +%ED2%wN,؃ 8 75C6Qoހ_ p $L h8ze,F>O s"0K/zF>t-w1Jy{׊?|-]*_u˯7D@M\!]:_'m\7u ~aw ڲ2:rY:{BX4Wp@b_g8CIzjxBDd1^}6u :.EoY#'+} bl,2+$b0 [exU!fT2ÞgOe<:e1VU)@p|̰[Έ&eO܀[x+6#7a{T.Q(8B#cαd͂Ĕ-47=O5(,ᤁ3{0\)Jɂs90:tNA?Gb \6娓x2N/iMLtum'rSc|Į '\'d9m:3Vk/\\3LşY̭F,T0i2SM6j}'+ TQ;*I`LeWk ǠQLOiꀢc(Vk#p6Aٶ8-toD9=I?)Ju މ]f9=DYx" 19WIsy 2^wp#_xK_laYW_ݨ:"{~XǞZr~M+]@[g+-溵[A?f偉jҙXE QD'X5W.Z.\Z:hP]f.e۾9'ˡq KMhxڇ/Ok@]fdRLGsus`rSkƘKԫNUJa:kxcOKĴC4am* B# o+P|15ky{}b츇_΢4bXH:I 3:p wVޘ|AodmO%)Tt))S$,|?6+^BTdS R#Dž.rs_P N};mrϗIoIv% a4QqM P>pi#R#(OWXIJRjk@PIy߻Ņ~ vԎfCcO"|['T򊋲B@xͼ{jOnKV2+m  `2t|_C?l6 RT-I s.G(?rA¿)Y lik4E371VD3(Q8l~d\YQ/^uI2 at CT2D5[p0 <,"O*Vj\Gx-B+y否14?8j)İk GKj ^_SNxv3 Άa@6 Bz F 7>y:<<&t Y5l_r~ =`ϥ vQuqV4i@UHnbD/c^ "@ tRK}!Mf%w@*yA;#a{$f-s}(/UݙYY'{|i'$VC!>+<)#'V/L+)a5 2u!܁Z؟ ё/C쨙D;IݠhB٢R~J:6L^rKy %+}V~B@%Dz=ٽ.neyrz=ģGU_'STuJl}5u͸U<p8E{+YOŊˋFs(9\X2eѱi +6If`~esiF*x.h2(W",sMa Z iZCkj-MsHLhӖ6(g$3Q50?Ŵ<.zJzf1 3D]L"hp"IܓFXEd'13wq@tϨuo8Y;E#(-tj#Іfi+>Έ$TEd k&҄/An~,Tt4Z DYNm2%_D"\p˛Z%ksE٭e ̓(l(K")vJg>> w]G8>}O$Pn4z aNoՑ\P\ٖƹ9~|N\SJ覛+\:Y&Un0&9 (Qc)wV7}YK8zCbqCM PQS>OM&CrҼ[/wx$,JׅPbPjB5oru|3p@[@'hLrs .w v=$A@u$̗wi7cg@3;C`CZBf;筘<É9YoE2cXLŎA!ɩme\B)]U 0R<z\uq ޥO%O޳2΀b(H*k Wˤ{oՇ!{5cg'vWEiL),tfz!Qek{,G]k jQ3 \(YDsFCLBSzտ`4؎^W4-EU9fɏ#s8q݊ۉUהaw)} ؠ;mNgf1诔GeE4c>^x P1>m,&<]3]Ea) E}mbPQgڴ&~s,]Qh>dNxdť֡ސ!&LwR〸2˦QW+&I$2Wvдbrd-6ehNL m]PnӍ4XOW-HD99p)_ ! @4܈י^? Yy0Zm D^!jODL4@̽Tm"kvCפ Tnw:(CFyo4g< 3AAqW.UobKJKS {_'y4y(udM?.鮓r|Y0W1{}2up(pGp՛&dTQw_J5jo~ϫ{YwqNJO5LiъJre2J*H3S4oPkiɎ\(wpf,'=P-I\xG/m]urEcMy]C10ǰX_C8C{1cTy-gUE</;_EuE`4B)ã%y߅ăZtejv!Ak?c/fkvdǝn=)L5:khKPXhbl4B9e`C>#J/ aA5,=("ZDCK0~:55CD0/.nUbXZj6-Z M=Q#Y{^J?.) ǣ xqm]G"~t`ǃ{,1#`Rq uX"YKɀ$jJJ ^2о8`mgenTd]Vo1Z;߉O[B}[ayOWm؝W~<^ N5n'9{ Ebz`j ;ߧ'|р]$gIX)眚i,5,^>(6]Ƽp;̒bR4)e%BU8HМbN-\92k`m XdX' v!53_hݳڽ8<9(11xӛ+ U ȒGz9_#js>(r9Pm8,(QSO`S5=JCFLjn2-Ív uO/Ι/f-r߀BN^|Gn͑Uq_i]e$Ka3򕗲℃STbRuwf&N 4,B47`A{h<{m`;ߟ@3nhH 8654^4*F,<|0h{v;{jn%OotmYkӫic*MY;eMbip[-W9R)[Ըi/0I~yR%c?")饳ÜIB=粄T wX=HZó#/Kۜ2H c\W+諻/t5^*)Lke@7a"N wЅ".`QT@Ի&w`Qm2 ))1S+4Hȴ-(!/AYղv=t/5~>Qbdi[PR7YHU3K6ͻ_+8ȥIEVK+>Yh9ݏrȻ)#ёB0~E%Y)m a["AۭΊE 9Z Ia"Z݋'_k%SRw)$P1&`U"e ${k-]lWV^]zDzHDvAs]0cb#FfXbL4[ɀ_t$b8)cdreZm=ӵCI}u[cxvp> 7L|"Z9Bb51ԙ'P,n1 fvTaP +Zxz&';xvԅEXPfd'>~ؗQuVJl6t{cw',BIޝw{t*L)HsP빀̧G` gzZ.@Fec$B+ߏb0WE]CŸT΁7}z)ri,5% 47|~\@.|gTV|jxK,ذ"GfpYEqdkǠىYR4)Ē4͵9DDE/?q:kW)W †#QeF;fЬ`2/%+$E?ҀO}fv`~i1pÚ9)}.ż}5rp^Ί~*Dk爌N}H6\#@H$L$&LߔmeŜw!mhTHK1=}GW%2D͉aP2A*RzK~7i5p8OՆ#xe,dipl66؍>Q gfOgWK)ٖBqoC -KwN\1t}=*'#;QkwdvPLy 7a`KЯ o?1E3w >U? >N_6lZd4 u.y.Rӡ2<9eWW_I$S-+ev'|kXuJz:h%r|(C]. $pnNPձ|E B k}8 УgCRc\d)+*YTd]D^uD6u0{>h%r.و%Pc;D$ U&[ EP9_[;(G <Ѻt1"ѻ1'Ef],J^OlP&" |be*=2| Zw S ݺbKۼgZ.[S`^ނ*K+[#؉0y;]P9@ԓqҳ}vkFK@Wz(t2e19 (T7| 2sYTe;];s#@*]zs v%TG1s*1Zf71ڵ;ҼW%C 7js;2^S֎IO^|6oZwqfe ĐĤK6s,󬫭J{DTJ4+~"`7-ήgh  Mfn*[4d2#$ӀϨ+^h6f["Q`G򏁤Ȱ9 ,HexisˆȠjWDr-kyZZh3k'J5r؅# T4(U\z5'9Bjum 4BW)՜5ts7P O q*H[} 3{Vc|<1<46;뫍)fm'|LvݳvG^ՙ2"/g9Z+Y-~t#>ıxa&}'~V: z&W\7 5&A!<ȅ :53,ٓS[1m۳<-!TeK'?/V=P~VlXWfEVc(F2}{>'hj<8FBwIh\qU䐎&ݻ _+xFla' H!)4IU㔯vU=\G ˧ O Νr M^ l-&2yo| ;t5#$[篘ErG?CZ1@~30owV9U/Q3 i" LXBSp اMm]$?y /Oe~*:a6xa98,Ff{F8a[K;Ѱhm3׺;bRo,XCP?fVk3[#ͶA;8{(.VmŠ:ksM/0ܫߏѓ)ÃX}uIݿPJruDQH+xKaTY#6θ0lUrNZa%RVYg~p(sK!|<>XY=TxTҞSh`*Ky)vxՍ~c -z?.nUQr8 AoBO IFSp/&)RXwA'd+({VhZ~ߏ:84OlۨB*t tDoW 9Ao/{4xw~UtG0O 34$0Fؾ4fXe}VGu o;&Σ$5.UG+0Ja[2m sz.!"R`'rzW{Ӟ,LmwEXG1G\BK fh2TRȌ k1MZ=[%XD)ZV 3<% 쎃@e.U|< st+vn~b~vj/V@R,$̯hZ+ F#'Se,) c\\3tV#s%["jg Hqx5`Dm=:ݕ|!UcW* IЊBZ23-O0dz!z(~bi.o.NZ=DmKa}"f#]w0D兪x'| ¶B9KNCxheN y,vrdbd3|t^={@P$ֈ"Rg'H!QI{#TݜД\}(!qBNEZKŒÄ!& -1hA8{Ҿ.="Ɲʢ$\)GX%,!%_k"%3gy A{8#{+W]XJ}o4Z.=K)7y1 gY-?n@߾%$=4;Dq5=78Ⳟ] @scp`6,ԽLCWJkN5Q+bg9uM㧬Am) q")gD3XNU񐥃ە@nGxEn_ 0.=7<gA] c V5F*Y~d9 =f-zG-ĺPx2Cu@OJ5MGbP'V5oJCs9Z$.~-s!Q+Y@yFcx]AڒA+a˼.NWbXrxI>+a|a>Zu ~p#êF?DQpR\V4ldƷ0[mA[=2tkmX*O;n)l5edDE. ̔yZNyY{0wcHKDKݼb7Cm,ĸ:LO#5+ym am92kׅ@<M$ren!|svmx Mߖ%ҶÁ(e,m WRʉR\y-LA`Iw_?kZ*1V t@VsQ6%ɾ&s-EQ5/ƴY[}s%O>{>t=ťvNܢ=&> )ZYo۝`CvH+SS'{k6y/jh^Km,m{y^iv+[%OMޱu;qމNt9riDٕeV~y_(S SFCb{@25iO9d›"1?-{t |ldV蕭ox6໫x͸$p }%?)V1sCcM;UV>Yiؤ4:A?jŃ ֎U@~ŅjjPā :m)E QgltHތΖsI _v.a8Kql@[øWӨGT`5wT 8ӈHlZ}˖ n #E0KӋ9`ޱb]Ƃ\q`cDt&bE$qAk@i %bgӅw EX V+ Ю.Xహ#uک&e'7' 5 }|( Ě7 #ėo4Yr"!Bڅ`F8,4h~7zi+ Y*^;׺!3VjhnΖƏ`]*(4bPsKaC]Kbk# WVzؓ=ߗZ=H$ø\1<T%̿`a`Eƒx0|AZN2\bPmEb>٭ oɚh]ɣnKQOfjQRm=wHfAkꀘF謟`RβUe<ss]BxX_tK{@$ _hXLanZwm*/Z"cMG=nqmNImăHﳎN%eӷzU>ZjO%v5@X JV.kž&59qc52(LZOjZTL1#-wBFY]$+8]=lH=0@V%\A݌4^$4T%pp`Gߦk7AVZ#4?|^1ÇbUr5ĕ> Ιng5%<%X/*87 lV~mRbHpf4ȈuAHB3TY7R@mvl3b: `g8#Uu凷*nfibDDb#1wPU JNaQD '7/XNoQP v^:s+w9, m[ѺۯK>㻇ot17P;7MR4ivT OBnI, l} ;݊g{>rq=dư2Acqj UȊ꓿V%,cCj&} fI& #caA݉rSk⵰l |9ʩ]Ԇ@k:J,'k 2lIq|~2363J({}49XD6 Y-+z} $;c;^q+壊Tkw47'!T,a2kʾox YI)a9zHuf#Tz*t9 RkYW(t `P3f[FO&^#{G{Ԉ'j'Cǟ`$xՆ"?fٚ`ʐ!jY0Qe |14B\CqOoaKmg7[1~92&Beո`Z'm3#Xe4g`倓ĺm+A7w¡&G{ Cutx$\K8x}g㝓tnQͣ`-ͼ 0tZ<\8?Ra֝RT&W!tkpBuɩjA6_Gt L pMP>e6/uDW{dHr3_N)6klx5Sd!Q?6k{%7wu^:[mfΐQ|j2Ah(9- 5B[ީDL8;L38:z u>x=BjFЙIw*W캋( \hPӇ)dqEl]^J%8h ѷ>&1-h҃yiƖuW5U ^5/-DOgt،y Rű*X&CG_,V_W(N59\I`R){Ew N<AO4Fl_]}?1N+j^,bDy/_U[#3L*3 O4mG{^!hlb.StްR3&8)|7+-Шl) #<hclh)TNsFMOEܢؑ>`An&mndN+n3!'꜌Cj$ý LEK?w`(2m!\F@#l* o#Bx38J_fjl Ow8VN 7W F1 Xx*I8!]ª'Xd%/.BD6bUcm4̀yb4kU>O Uxn,?੔A [Myc03_1bF,ٟUҒce 'FKf._-{8qI[4lYOX®DFzEƥBK 4mP P !N7,d Y*$r; cs䒂 G'yܚWIbdpV.d0Nqs:圇fH%w+voy8:0;C{(Ն"^oGjW"@V~R4'CF6}9_Ԣ+kM=kDbuDV6öę`hZ[sVѹ<ΪQ+3EQ]D/ZLF23T{ !3q$(fgyZXn(A͋ߍIr89/|'"'ק3̤3LC<uv/?dFɅ&e nԳބuX ŠH%1p'zZG1'Aڈ[w!nݏɖ"58eiކ$qsc|>֖3WŨl~&+%8&q,LLӎe٩9{Wa;u+פj@(ekl$uf<ߙŇ~"fo%m 7+g]J80;bl}S?gXC%#+p [R3WqgRNӷd~@=7WOgǹT,^2ْx^-(YihY#fYٚiJܠͷ6m}EWv x<4`FWNc ៺mn3_= _w]3P֨VzKP$#. R6_EaƶÅjiBA`փ;0]cSI03NK*oZuA{y?8!;7O ;ZZ');JQ!@JQ5/Eod~Bõ,{jlz`ٲA&5lQHM1bMܲKĬQr隦=Fbʝ_*LHU a*3+S2Tߺ^KMs0~MW4j;qؾwNnq *&'xWîY|zMᨯB\ۊl% p`__.%2-e˸zzQR߄5GD}:#ԫEԙoƈv:A9u{STpB)K~OG>:jR&-ߊO<>$tYEBi[ne)&r 0K{!q!ϰ&dA0= ;KanG9\ñk:+Ю ^WggŊeEʐOFWoG{y MguX3jYX*z7cสs->~6w"@hCaBld}108~5-)07<3j ]$35vW~@xTæ|XvDK9J-&^,x&$8)Dr#wdp[a- s[T' |4(f]x2ImV!"TQKc\6650 ,d" 3G*'wF^ʎ D`olDw 5HH VEX7 +j$>n鑅<5mZ1}eE |a"v`GդWIYȮQ~{}XI!;:Dc97U06_8N%Ø(CFR`('v+rM?>CW0ګ8)g[?BYlϷAlّyz5SeWgcCJH"K#ᐪ-6 j0-UOloe\^ImwwD+A/_?%c=sj+/S.\(qb>ͭ V̐+ls$5OS-?uYĢw,%?kRq1CCJ ?U57S@NCK( 777.aCX.7)w{XGȺX[J;{dH }3ԁrǃ~;m[ T|oP4 \C3<38i7Ag)7~nP+_ ۃ@)!mJR' %.^" uM(ZWMghsmٲ{$:<7\hIMw>dճP:lBǞ3ߘaz%%pࢻ\Y]#=  GaSz P@Μp&'ZO D1*|2y:V.CNQlƋ?9$"lew5JG W5ys1388QNƷנ"3<*A.&pkvwJp~bs&aRVwX=ᷮ1m=< 6N%6N?n GgMd]CmT֊SG8:NBJ+s0K Cu Y\i+Pm_tYǼ\$A(ԋ}W* #"-:v`57a=bÙuFNf\*NFE*އ{Pϐ"8ZK:7U A1)#,!e2;!2ʨ*zyqrZ1 8d|0.dCK "(bV SzD*CRweivPy P}._W.kr.ɢzI8Zf_L$t{{S mϭ}{k}uATT: KF!?{|gWu~GRuЖڞegɇ0ڤ=I--z]˦x^Lم2 NK,]cxN^LOGq?K;׷3AXxErPo3D(q'`'OPD+"˓Vzt۝mW%d%8t`xa*ĺ;IulYPDNJӇg~Gy,|Ʀ] Wzm7Xld2yr"F]Fvb{0ݡ Ei*1@&|qHPxHZJn ]eH n.N8 tlu7q"Wկ1m` g4^bŸ:%;+PTm EjU+xs/{ GՙSPMi~&FBYJG @"2rc2X@ ΓԚeݳ։Z3sYWtE-,UMڷZS^Mx>:CPIoQ8y> D4JW6>`SjљU:SuY"q_%$5ZsÛB&(M:PQX YۡpphH Xj ,S2:gY*NVMoT@J,0x Y>hdCK{Ab>g `rYrK5pz˺. .hԮ{T} 8|*,>`z9㦤h fCS$d j89YQCALEs9-{ ibp0>`VD-0zEw}ik.G2|"h52OK'iZ5P7! ;x T`9rl#p:AQ ,py8qX}7D0ߖ@(  jTQʜLUM69`h'h A=IFي$yņ 5[oR2M])!*J^_0tguƐg.u' 5Mψ?h@6REprZg |j2? 4b5< E.7B՗:i븝."u;nâCR#"bzs`(O䚼:\y[;ykM'AV(N8MrIbV*RibS%o•jc`^: -S@۲Jŋah*C7,?JªbǔRI=a[Ǣ|T,'1pLE[gNԹN-=)!1&f Y~Z G'eI &;R {ӫvU#촓P4{ed!Է7SiHT.i8 '~GW*Tx 6Gi#nzܵ$}:dTj☧wޤJ+n)cb }# p '~3O&}A+,iT6(MbaGyvmO〞<bHTd:w4o$ !ҝi"; &ZJP}$W .DV+Тջch@k1F:rc/EMa#ϵNH/poV}h+UT5m[ y!>> &KbhmRb88OBv^G{Ej+c^'^H@׿W2U"> ;6Z9˕MD.Xvd\hYzB]8f@^Ѩ ه~HدC|f[i렳y^wV Ϭ=vU" 'y V.<;tSřS T C}: _AT}.W7)O?XbgCV̧l`#`6axG`]\͌`վo }CB.tgC^LjD9$GҘ-wBPGj`E4!CmՄӖ\pf:V;[ s , kΥ3z/(b|wTW*U[hE\̉=1"rՃEN?L7J?}p{t@A5k._Z,7XeL`V"PvSsH=`R(voDʼnGyZ# 5w`j)TD&#V.p,u:!\nA_ɼ"Lפ/&%|%tts,d-F:_'b1CO FR2oj(r޼Ms@ٚ:O菬&i%J1X?e%00jV &_M8S{*֣KUy[ ?ZץbDDεb""a]>V*q#R½DeMve &6q.",=UYW. 8fB$n?2*÷~ʡVTRߴ:)R { X -85H A {O9,8~rZsZ<B mt'"?vx+G [}Z sdKa#_pdAqse4VDq꣩E6G`;Ҋ -o͠YrjYfDhGjR6 i^b6@^@< )calˮX/1㏺kX=Vw >)Le?wG '^"@q%XRz|.yA;Ǥ 95WMQ"ix m2 {Yn  TM*yw @]{ڏ%N4'^ a&4a[d4ԃa7V tm ^N˞>c1 {J*n+%ٺŭ(~d5Q1 WkpRfh d%6XyxmQo~(7AY[H(:"3ϢBIH?_D;Lg UΆJ 0K'6wO}"OnbYFkŧ$ڶp d0 QAhȌ38$(9sI "D(ԏWlb؆s  #!Y UmWMg]WQRg$*8]U6ω;=V-S,EŃ1TF!@L?WKx |5#hYivV\.&qH;9=^dd1[E$w*SFNGIFb6)oK3f\7:L~Xl$D#ҁw !Xe=dc#Mo*@,94k'Z w[8S{"v܁״jr# T"@Y:^k.N:׻wa$gB4ŜrE:)ޑήIA;[`iق- ^-,u[`4b½L<{5ky2XMYctEQ<^p*K ?$ؐF)UI<Ti[7½=Z0<%-ֲ@[L/KnJ/jf SҠ}si?߶4jke|'9뚘0˘9sTQ7KN9})]w+QEɅwёU0cFT3Q@z2;G%Sk|]? ۚg X;]h:W.աjɀ7S9,}IkY ~EHsua*b9M. Rg2!kOO @ 2x܀$kQ^.7q@dݸ^uͺNFvOZl`L}9tsPTuYdOߵR/NgR_"y7_֩i ʦ%2Bi#R_Awʱw!|"4k;V*E^Q)@IBfs]”XVa'`QK8W7Ny!bw[ M]}2Qυ+􇻄-JOaj{X79#CN>lVb JHӾF :Oi_K b8UC 񄕓Nn?S`ϼ*7.Iseؘ8+ 'mGvR=-sG7uN% [CH?2xǑJ 6Jyj5rc4z6ŽK'bU[wg|fZQ Jˢ<!WM;ei,u !WfܱcLG% !)* uyЇ@-<׺!*2:U@tq&{lX`j +WCu,%C 4&)R P q? 2tp没_^eDɯonr&)6R$Ȝ S ,:R@>HHܳAP"š]#MۓY@P0u:#K8B܂6ăUѝYSVz/܉Eoy%.C_KqY"9w#p:ۅa"3Mz_5OT$5y: cx/;;Qe( YANvD8x au0mܥ%u.(xC 4iO0\ݿ; DRy!W\RvBf:V=0] :WHB ~vB& IZZLuVMp2@0rghrzhR6-@ʏA_1ӫش` 2ڸ/n=G.!Q~lѩ5`s;cܹ>[4^9J#}̿ jc1k?zߋ򝞅5Ą"d: lx:XHM\'0J4k7T2 ˯aiMm!UR(>dBda< Qv@$JހM< Ž^ j{qQ\JwTy:lsiȔae5&l.q-t\$R cKU1tCi)=?$5zCMObP(9NbH6r0%_ kӁMLvseIzȠ'oExF֗Rgjr/22;,^0oH3c ,|{yHh1Ɂ,^!~`=a[ ӌ2``Txx!vj)֟i|utT$I;+kRƸql%6hlMzu"t˓пF'=AjxK/7adl•Äo<[,5Ay%}qTBXSN#:=/)b]@^hL hl^I w=_}>H=֟X|V H }.5Rߤ'G B G37W N N; \;EcrpZ C[6ܤ@."MLfauNXX%-ͳWM%IW[ X;?yYZ \2'n-~czr$s ?q.'uY:»CfW@`*?PxɨTJBzU7=n'7pA$\SwX*U[4|eH6ɚNIfn_ԍNJm [q?s|VXbua=9CzL͔[iI7C ̹<ѼosG};NݽZ]V !h:ZafؙNCxr&(Tp;&?X:_6Ex5cfg)g$׳%8s2C!=b. Vzfg64שeXk*0so\ctk :"1m{ (Ν/I]Tj 5r& ?f0*4,臇^LdY\rdTI{cH{|ɤ-T#K* i57ZY-]IriL=XC-vX:\>قfmdI"Nk"{)qFٰp.χ ޴/;X40f%[[(RdQn.>1I9 $#f :=_m&I˹V At- \^e(ba六YIVoꟉopHd׃ZləG ܖ|w-&D9@)4\b-tLrqbq(߲hV\-;s—AZU Р義}s+эeК #"Eh09 $s>LV'^gE>"]} dUrMmH>zf`*AZA×,4.Uu=m,k IP!AH+ǻP\%aE#ZwQZsݢ!a# ʺ)ld(iBzLsg68 [mʅ;{1~$gEvVJ!q(Ϣ,V^Gt(IbuT??ylTsdsocu>?0;EF>DYv B]dR@v;Vu]&sbIC*vቐ9މR岩wnlP{dĥJ~&Z)6X+hY6Qk[3*ϙ"]KHKd<+g>Ev28k]%ƾ&5Z9)G]88|욐gq/'mV`<m$nKb0u9P3ϱ[I'ƻ߮0Cs:-Ija"ux'DW?p:AP80B66Vor=1%1(M]9լKgmm2| ?|[A攧hgR$D+%!#J70jeS|í \ZRzYaJ#t6PʘE-~eP3Eo?x#}\\Onc)}@ : B_8>>7SY],6hD7iʨo gKuO9Y^vk4Y x'=~mYqY,m_u# ;̭cD4=jƥpx7vuE %Wu\;61l6oG^2TndwmUdO9gHO:! gJok"kij~]!Ir=&lC *’Lt\~Ք8(9aGǩ F!+3T7AM'UU;-j焲 .nD0v͆&W+%FB5fq]|$p8xؐFfvTb#гUR2l DZDtN?;&E Es4M1VsDR2tGҨ)d*7b$,pDNKO>[v~`tV:r%eMC 1,.jZC?hs%~i ~qB)` W" ; yoSrBy1u[2+=4otc.|MR(e!yM9`}mFpfINN=Bwa9[2;*Yk_>f Vr (gBeAa(dgPMjoNVH7 ^2< A,7ѩ(]Z/'W}Rs}(2 *Ok@Zz{@=# e:W"2$V>7227Xa%<TٌnO|}3RxlN9)8,rdq-qcPY׮ GT,H#Уھ'b8ٴ;neuB0_GjNc0NdΞ7lؾjdsfx6Ѯ uz8/M.&=ĜP7k;:PLӎ9 ź;祧9% `Ze =-{BUa46cں؟"&U?\Fכƾ%󋛤 v rQPVC!c2?TUn BjluW]NK缩@GVRZW˛Xt߬$7`FU>=7#T zb h#%ItLTDA'%mZhͲ(dDc"f1ϑ #穗{h *IFO\ߏ:g}q#O(lH ՖAaKӇ x.`Gfo=٨!~sV:of䁇]$F'U|VA(nJZ_{2mv;Hez`FfzxԐuTBATr#WߕPrZ e6t"9srQ[}+>|[9w~<;AmB>^h;+@3C2GqE3{M<]2Bo BP,vr!ewPOg|"=qĸ"[h!"+& I%Ά5d6n9EHe=Ƕ0~7{q"AmNQot;e1Lvk Haj{DpO6.iͥ2j*E%Bd&R_ckj$1/hoٯutل4Eԫ Z?2ZgԲYn,|<t3{^`g&BSQtlƿk!϶$1 Qb,QFCM*EkcۧXyOəz?6:!;{IxcD(g5 jdՓ W^(;{ΛA7p^ӭm6Zxt_((ބ\! Q4d= % \pqLf Ҕn`r#lZ(I߻I6DGE1Z@'RF61{T0%xff?_4]P4Уbnx(Yw v}\'f&23*95RꛀXe]N٫^ESM2ҕB'&³{g"کl"ge(MzI|МiIpgLN fyr3Bset3;,2usnwlVR"kHRՓ4LP N v#ݎs+ts"i|gp7Q$NyGV_#Tx Q>='ϵ%N{)u(ǑO_B3{ay#!K#<qg}]0^s`ffK@r\&=lGab Qc{ gW -ĥ'5 rö́; F2(*"$! WA1\ncXjMK18,ÐBXop!"a .>Fly<ԑf1ÒNde2 HhbRt,(<Pf(QK̿hH|"8u@{CE1kaUhkc` $#/~ZnFL) <}o U>hKƙ >~ '0x.+&ƾ ]ޢ(IN$Z5Z98>i/Y1 Vmxݷ!F;.@ĔYuذB)G CNtX|$4:S4Y2ɸ2K>-FNLsD6fص9Pa#"tC4w{hG Ni;ܟNuAf ?m'ė(4L)0s홼q m|?&bǍl@X8_TDs;T>HyȧgZ'd D[3C4+`q GOcVs@=V"՛8ZZrs]݊S„R CsSؠ En1 Rv&QSޒ`iO&ba|{&km?9œ;ؐp@r+ T-kAV No's)oPTbi,AGؒPYgKU{Xyt"!bCuЦ!`aЊqq-T[}QCׄ ۑP5of @RKhX׿̶t"`fF3U552߉qtڢ_ѐDۭxr=mÌC"d sSQM$ElPT8::uCujJpI:NѕlSOVWV?tU<ʹt>ߝn0 总tv@@n-uf?jD5cm7ά 7Eqcr (3&Vם(cu 0'gnpO{.kc>V!/=AUoaK vYre",G8}b~ұOy0pk]]~x(&R_k:E#2}ܥN-(Cq] 6BM7S-q[כ<ԩĹ ?^dȢ5=`_&]?M܋?GҤ8 L4XjJ*!#J]"Buj!WFBpWk - c {Y2=|k ]44'ia+8!RT=FS׼"Os뜳qO~.͈0,*sHII[" x0e""SFz(@p͘!'j7tX)-`G@oVS qj?7 OjSdy͎9P,ʁYDq 79Ø=37C)y]Y}Sf±ōVC9^1фS%,3۱Sk 3PNNhĘXqbiEB+[v 7~!׷:E<(فv12Iq xJ&_ |3q8"E=d%(q,P7&+`D>/nAYtćt x]xϹ+q 2J`xl r"G G2\J] 6Mz+jl)Itˊ_2'!k`u9WD@ׂ*C Usө"MJh=E54ެ}_t#f,ƃrƧvI'E X4,> n N>I<{ruI嚝0MBB-ZKl߃cN޷ZbP<Џ{m@<R ~RO>w csl$kEVQZ^Bs9*3e%VCE16@#ɗDXB05>Ǽ}0 ޳pTk(uy$Yo_3 E";ϧo"cze֖IU-̓Pڼv vۓYw}Xb;BJ AZѻgrI\o 8(P֍ܶ" s_lqƷ#w\:W:c/VFK$i"4*ܥoP(pc2n\AaFkiIl=sl\u\m#n|"^g`¾L(|ֺ< j֜SNA2?`2*׼ ˾IBO1ػ =5@ xLO͓ܳVV7` ]\#c&hAnL2:v|ϸ 85ןt ! ~Ps-||\~?xclfV5g-mY"i-Aj J V"7|̂A |j}9h\@USf?B^o8u<2AǕG}{Egx -cuQ&NYԈp0Ν5ZN}6YIe*IJj}|fSݝ.<}XOx0mϥ`@з*Ȫ~9/<Ane)}M,RWv|N-nWf 6|c]pm`+ bW[pֻ5{j^BI]\ZoEP/o5~/mXNM7Dϩ3PWDA8Xү/^俖LI;`(E/kDS^m_=QE`S,\y rPc?'Z!S)O}WH&⪂V\ݶu Vr|V@o֩.Hy*Z߈2R*o$xO^ת:.iIޱwh/##~xe ogqQiy9 &Fn`2SJ[ 9*B c=x= ,zT6U3G0v`LIܴ NbYVKDhLvg趠PD߭U kPNt%/c`WDa-x'@Q N8,.gTlQH- 2h`UIc3QgatGǹxpC\M¥~vVeEQ03i7T_>x]0X-X%4|d,1/XWmG(yP[3SuI#1 z@I~x?ϷiġD8(rP[V YzX^\q] @]Cѳ],AHv3[BOէvґ,CAWFX!!ֱ!x[nw>3"5&SA/b&9Z߅?% M6?{JھzkIio)7/0&ZgGE2 0QGmC(<1kcbbᙶpU^gɠ4qCoP+\FW{hZ67@t(%#6+-_ '#7p{Zl0lCw*S镜N`DHb4<zk~#"'W3rk}_=<;¢ 2Cy5q{#c+7UsJHm%9"pVM M#>C@Nqֈ&,e{Qz+۟S&pO@uz{AL%baHU6'öW~uډ3P>CCwr[a̵UkjRS"YOXK6L)ي6OSR[)āzzK<>KsC7yYaJE Ġ^\^~Cv,A>K/٠5C; vaóit^HIR̍G ^1UE[8UFƳKWYeAj +6O Ӕ&Nʺt15f:Og?$ zb*ɘɖ7L0[8`nY[F[vn΋o;Ⰱ&y5v%[ j}"mvunozS^X6HOIdAEhc o:ˏ:u0w*hܛrtZsGeNPWxق`8M(JA@cωjWVVǷf_lJ:IY<ׁjB'Ue;=\[lAOM5|Z n^OK5 ]ܮ!O??k"%ޟHThDV BsZHO7x—H;m}OS:}YI| !]M<6X)  4b ;j.}6 ~euqDk"\g3cEW!!8^xbAE.*Q5a̮ 4U)04cn;21N-i+-d=ƖzUT l?8A{:sgze-+H"ԏ\&!Ru]M0C;o t#0}?'TNДa |u_+Я &s֨zAAbmaq̢%r8:ܕ{%X\o=\t'anM4 HdH:?cc91e_e4J(ltےxXM0&R伪|#~d#5XԠ"HAZ0(kA0ot~dx (r)!&F6]yDαM7ЈkXy4yQ cBqplpɃ#;!O]&ANn QR蝒ON+~7/oK`_u?u/GilnNm-+G!R47lɘAd^3 D\I-E/#U,N㹆oDm9Q-y>/kU]F'w#&,j.('Buf>FzR3IYm)NQ4hiΔ&$"# g߇V^4  H+y~lvz熳$8Xh-xK]~j 55d!^ f˺~Ftv~Em͡7ZTy:ۤaJ*+(v"z:=cG8+ Ә.|j2bYjCho)9xe/㤄844TYPe7Aj:In;nw?.adp@ $M +Uya!Topf+Yd*Ssp:[LG6 MDdP=`,F[jK2K^T=W(Z-§LU6E-A:#4O\uYϨ OIUƅQp=Y/{ H`h|:fͲ0".kRۨe,PTo Ѕr WtՖmw7&0"z +_뙽'q 9w#un݅hMAtkKj쇶d8n䠥,4'sKX! !h 7#{H.^3/{`fvV%Lپ[iJx&*1OoN! her cEEn5AtB̸#"EtSwccg4YEl7Eߠ}m<N=yn8y g7]JC|wF#̈́"Ⱥ' ެ~0YǼ<ww`z75^ e 3WtDu\$í3H"c6:x@16PO+QVzWڨ84{}ta#-%aמakR@s,E䋳j{ WF>TD5{DupI628|B(46":afD.o_ р $"*FՇv|dE܂@T1~2zmTw^A%#qL$vj˟z/]fdjL.dy>U}k!u U[ϓE'1Y'ه[y뷑VHyp$#MBv;;s~t>ꮲ):Á+`KN1f%:x!޶Csb Ublʛ/'u AT>`a;̎줎<35׸WKٌ]σ(aY_sUc|3'Cڗf1-.8B,EH0aBZ߻~$L,֐~Dy 1i*pf~+j$NRg[%}qI!R;|g@|:i"0ՊnvW_i1Nh&)8W&Ow)Z%싟;(\4b93?wcEQP!)aP={ nSX;*VZpm t!`Z,ERW%M%UGz?Һs% Dd JӸ @PcnpLyȩk;I81˰ AsVtrt!0.Qf `>1`)!\ѩF1F}Nwxcwqs |Fy22l1 y9= xYe+ =\Vpi5Pl60[Fi8xTkߒְDAпV\ DžB¤(;   jjMGdFRm-;IPE]ր! /,y{ w:2?蕰txD7M܅4\ ?a3*zpt %vADQiTڥ#/YU ܹ={pK7Er93<$3>Ȯ%?'?O>e1'1tW7dVXߏM´TӬ !>77R}v~KP~2K748X\A#KC3e}vnr`V(߇3^r5az&ZŜ]`biM*rky37{oa\A["v q*'fi4s,bEY+~GO!VA#iTYrd9:RĤӛ+vF۝ξMvP7wEpi0 V8v`q,_I:o7Wx$kl$rٹQ8:H޵|+A:E0qTOͼjx2+ iz6-D.ѱ#4^jy\ v}~j薏ʕ- ~% kKXK8ƕInc%[]?I ϝH׼V Qo4}!)FQ}L j2[mZZJ_υKw\hEc$Bz?Kp 7Iy#`ώlgEE[c=rCO=2掳S E@pd5}`΀o+WZ11,+9V=Ԃ/,9,`[[5bwyqizk#ibZytZj3C4OWz5XPs7#&j<ࣞ֡r0GؽyoOU\)RwQ#Pw\DcrOME|iUYzm308+Ҵ+$P?hVL3BD,Ezɻ叠/8lL]v`>}kwp !+@sHunyT0JP p(&w'XYI[ٴ@ASƨO@: b *\MT;` 0?k-rz+wGŕh cqܠGWhT|A6"ؓTv+=7:@u \ Q#4C?G .}<,{GVJjqO'è= [n,6j*ֽT8ϥY)28.+ǧxmF%IGijUi<|KC uBmpMj,? șnauF2@"J0ߥFwT ʠ*Д;־7)mE]jߐkI5ڊuv#>Q9pK@zߍ}/*< + Z&bTC X>I+Ѣf뭂7U_+H7RWn)_k's%TՇǠT26Ħ4x1n [)P\DtjzC.lglX)z_cs,Tv!jl0}/rc5xw>` mg gOwf@@ tźݾiݙRB5EXʍ\K9a` #-mȦߋ{bL~P*R?zGY҆_Ë5xzc `#ZȽt듛EzNLt]@g0 K#Y,[X euRV oX*Uzפ>:YBuPq^˞*]F! ^糦 X5ԟY++G<\ǨOư}Y9=iĔA[!p ֊271&#GVXI[k "\UG=BCram[|FٶL#,AACjA*ԷXS1xj~ }ON="zy2Bp{qow;,j]jIalAx^qx̒$lW-jm &mI^NSR_-\2+Q@Th ?Q3lA-U*., K  6PۅWEN% ,Iuzm:S%pncfxTM?~ Siv?{(ŸP-kz/D`m4rIkaPMR9T Ĭk$N$_(ƬV`qbM?Dғ7%~Egy ѿf,W8]3;8o.ιjGgy^vYUxkG:ًAS޶ ^IEox2G mi^uJb|`xƈK;gy'$)=߇hEGПRO PfэV?C.oL;X_4޻N#*m7BWq]f(t1"!Tx|HhOG\r( D|lc/ؘ--al ޹pKR%{*q;ύx+6Azj rkY.LE^]gj:n܎wfÜJd;oy*Hu0zgB([*Btw>fTqk }A"SAI NT'ďm^/#0ۗg<y'=nCPw4/AHڬGj> P05|lZ \j@.u3ȹeVyx7.K +IZNs{x@dx93=o}:A`?~T6䒘*H\uRYi-iDK|fvTw٪X2}(٫iS~?gDqw%tM-2v+1McU ^+3h]Aftrq‚@vFB>c[<=Cނ\:4ug2(ItiySj\r/Q *E>J{(+M+CqggÛ. #ք,ēE [W*:k3[r;m 23 ׁgX'1}WU$jcOTC^*1,(QN[pL:׿ * ܗ-أ5-Tot jGnde;c,~>m6υ t3ݹGaǙ%}EQ[%~ ~-I}?X9elR%s;u[Xn }H5/ 䑻Lo?q-VŌn/v *lB^>Yp|rRLcNshQr2+^dʔuDgH*o7P3p(ͿK3,M>ʞ &i ɀkiC;Wx%3M?y˜3mUCib1$O2 b<'"0g eJU*j'-GH!_ryD^ Bwo w3C/&HF̭YW0udF&kGS6_2*c)6ͷ8xVJXo&NMb%qE#ibZ~Q=FmZnGσճ9,? blWeLbkUzre#:{hׯMZz3OVb)lt3n,{9Han8[a]8zȣ|tPjE X2TF>>s7z*ގ}#ہX/eWNnEm:V>8aaW.F k UԊi:W*'߬%K/- lLٟq(.@`aR h>C=4Ǿ/sNĦY,A[&s|ru"\CpJQҹ?@9!Qf5K sLt#Ff?C" >R@r yDkw{?Gs SJu#h5kג| _wg cppq͊u2~Ғd~3G+Qr%hLF 9 ;\z{p]Fpn˳e;L~g޹~Xq&sH;aݠ6|(\a3@PJy51`걜@W{GgS^p$"0jieh0φr`Nβw w N Dl 3R5.~'hV1a(Bgw} ,4 DgT.#@LoZPюM}V`,}HyMk}&OL yVEŹ z*t Ǫ0}qX8t݋8%GӴo`2G&F߱pTcRT0gj@J#`p; Z@ˬ&NS׫'h;Q G8!{Agi=r L( ?L?Cӿ_M>hzw}:HZɡ0ŕGs}i=1i˧t3ɩbA=`n >ݼɘ_RI>+=Y3xTu?C\#L¯0zs55qE^c&+:uBfM,hG!0&s-u̻OWV `?yAk|DPZmqFKSpY C= ]G{:tzt):%~Mvd 2ZmI'Z>uUO:lɖ-~U)?w<oQM4KAC!#9V; p CYL Dڗ iaG6ө!)k@{|U+^_HLa䅢yjum *p~eߟ4W\И(" d,Új8ns D `U/Yonj]Vbfh>Jب@DVZ2%w51$[sa=pp8s|&y%j[zNGhf'q \gTW]W7 ߊaj)R ;⥈lB4I[f<(?L_8.WDz[֮L~gw6AU% 9#cB`{SɚbΏ|`wVk97s*L0gr畦*[pcOJ^qm˩ t0" 7Dxonarh_yfz!fS*}N`8q7$RKεwV|G{ԞTU}]yU7*oV.4Ow֑S<<b|:&gQbzw]ӵ5 +ψ5i;D$>$R`/\~l\LJi_qYe!#~;m(cy,;M m.iT5oxǓ[U)pR^t-J/n-箈ȗhdhjrC'uHD{,j"?K/([HiUpNX+92zN/] #F!+I)ܽP]Uj |B >:l]?㛪jOëN *e 6W\Zgz9d* `V/$p;Cjr*%pq?$x_1 SroB?queC-֑\q0zI.?:τ|"aa|@?C!z G~io.hYgٔx7r~7~P:R+0̛e!x8f.x_^8d~`x ~¯g,[FOb?c $ Qb0S+'ce]4x w5Sx" 9'EmI4fe|\:[CFlZ?&E4TǺoBiR0?tt=k1* 0,@VQÖ4IxynHl~Ղ?, ʇW -zm(RGlJCtP!0v8\BSXyvQ\Ss 5Wsm'f)T9TԷ ;mYllV?;N# 1Y&_D3j՗E@go)Y.gi= C$mߣecJlJP'FNZkI:v #SH.C*|:LRDQ^~lјә[ VŜPQDgђyc/IWzUeWi)1!0qZ b&zֹr6ͭ:VnRѪ*;D OD^@+2@P[, ߃>[ռ N?dYJǹNbK:zx):&vK {s=+ȉB2>NY!Jl2J]6Ϯ$Tn7vx ?wA$Q b3oVy§'D eI|Zy#z5ҍҹQ{9mMm]f$3I`ّɷI*`j.w%2[H&٤XQblp&#+.AM26 V7ىhX@IkUä#" -|=7)JqHҚo]8 q(!cpאSPvdeƕwJ't $4۞yxOaK=ւӓӷE|]{6}O1!HY²- tzyv.Gu~ CG͠wڶggX@^LL,sy92F8KPC۵S)BM$h׃^#9(\.rk܈mYNMX*K+w ¦ΨUTeT%3PVURdǰOc6RơKgH[:VRj%pdaB +p,;ԉa8(h1Rp&s)bp 04)׹\oЃ_ _y 7~7J2gdA!M|›_7CllY՟/u8kq'.|ޅA :S"Ð`IM}*3&Pw"ޙYb]T4^+8hNDzyu^h6A&o*mZ@Ҍk[ȕQ.A+δ̐x/?eJuA~0@/Ж{>5ׅeϭAid4PV5;9E+1ҨKI4z5):"o PI8B;ԠGAn>u z^F, >gL1ݣ;6%uAO0%*R v<+ŀ>]`믃e}*9#3DfB-ڒgBuX7*,_= D$#Q?f=/2Cty{Ҵ>dphF(5*u,:`PU;Fۉts"Ĩ u(A'"I]lBVy<X<[KHX2gU%.-ht̒ >`WHG>wH߳kW9 kQ^ehy ''vte ?,sx Zpz5xgq.|Rv1o-Ph:0'/Ooe݀1}Vr+ T,i5{Jon~+;ZHcX>Q6EMREPT,A;zLRpJlvKH٫¹;˞C>,ޣ`ST^iz5XT'O=R['p3d|+YjQ4C«Ce45ǥcb*L/oPgɇÁӴ&!~]0g!ف/=EO*++`aAM^FcLV=-̄o@e`/ yE]qؿ=?Vp&b,;ZaB˼ e%|-j5\9=8hM'h%yf{J/6~']2 T٨/p4цF~3aH_*7Y^u$PUelT&ܹ;Zd <},ʉ5 j`TJzpI44<7–}[ .裻J|X-ںsj6Xw޿j $~W5@j(=a/n#!˞$\áz&\lk|uvifavr }&OKf E“UߢFZrE1@ 8t&V{Y2?BDZH uROngBdٴs{.cbWxAavP@T6 $6\:Hj ~|_#C851k;ԈӤȶ<Qxʾ2ae6"3b@)&%R`=#,L4Rab8iQJJȹmX^:e֖qcRGdj{]u];:]#>iXʽ sY+7BXx~[O#GgKiUySEg]͘~i^cR]E:x@ѵfwKҡ* 60ϸC<‡~~GŠR!qҍT4SDÃOCD:us\<_}=P\.)Z_׉qZֹZE]i L}NQBIarX"j=!-o/u\~,=gʡۖ)ԩN߬JK#jܢsiFqΝT$m~]ܢO+8X5w@D]eE {ӛ g" pyƽ1p3~p)1=doZY<=U 4;kG%:v>C[(M9zS1uli{d85gCψѕ;/TQ^QHЌ W2)}|x|jgI?vb}KD̨wU*XL1U{\*SADoyeUB_{Q(Vv>xdA_)產5=*U0ȕAo!E%vx4+%ϲ RIɱpx<< Q|2{v針ީ0 xz*62k+ 4Yu w_ڢX~+B$>Jք#-+Tߓr*h󲪤'lr+#J+?bN4zv/(%0Q3`hHY# i]p\{Vs0 w֬?fǰh! &_ y%t=M3۷ZuCٟjй솻X>@F%}އkYI:"|6zوB=rG  s-3aՆzzs{39S&B:6g E =g}%Phf%kmqi@X%h;8< p p7=w!Yϣc[D.yJ I["^tw&+{+-zls!6/DPcufjݨFo\!R O٠17u^m,bqT;شc\2~AH4!y -0/N][L֟2 iW{[7,M8c{u22g@n8eQ\> $\BeJlf%pH![b)gf 0U"Ŏr% iU%9Z[1<dV7`U|,ᵙ[*HF9fFs ^XOҘ6UjOH7B;̂6x]!5 q?8~`V7SIH{' r P97AdFbm<cvCG6[Ze' B˯*bMta,S%ozK#R_ zyiq1*0PH("A2=loLj/BU-_U$0 ORU~?`_j>nZ5]$Lɛp̟ XmfyuVuPU&wZ X֡ꪘ9 uI c%vh'`_SNXba@&M<>z`䈼|>D2rRn?'橼wQMch";FFڷ] @}y¸-'bB4un ESs3/Ī#wbh2S\7wwJnqL92<]5$cbw} 0VFuL>i|!va=9̫zc,68<<9'Huu_j?8OýhCƔ4EfP<)cnGR-6"*SKg;PV|*V2ekFĞqt21pyf8Hu_8) uDjjx{ba s #Db]̩i!{ZWiY91&`{4)tfZ9tDnEk'H)0k%LyY#U-@\x6 /ҡLQ-9ϑi߸v w/(,F-̇5MvKoPR[30 KB K0N>o CZd"6Y02ʲ`Lm~АoM8J2"3 dP[\BWK CLz~ux~(Ƀ3fJinxL(|V GĞ1Uѱ|T "A:QHqR$ ׻X%%$ȊC uI\5K{Rdsp{衇O]jMVF1ur Fvp8iM-`MhsǦyzTR%CTlA<҂8j_heHu#:6|d*>,ڦM:toyoM{U>}Brb2dZL,(T-5# X,+{}mߟ[UrO4rzz=po^9)ӨO\{-nB>Wx㣵77FFp8ohM-7ɅFrjJ("9CWFcr ~#P M(] |WD MZ1j::r3ĄwF?$2A0.x;j痰}%mM6ƣ|\󊧙kcOpDsN10%)X;2;VًjKIțٯJiX8KUUZΙIIR߲Гgm$͸)bQڒ̸\k<]E~0>T$MysʘP10'+ҕ)swmBKߣb7sF>Dchv|]$,~׹Yrxv [Ywg|%(꙯Ǩ. ̺(uqaѬ76؎ڕ|c҅o$"y,*ac(*PI\'GA4T/vűhus'ȁ4id- +&b5d2}rNx/B d$Bf^l r`>Wb :W=R.PZ3k?~6b|f@5fb5_%PE.~6\3+#o>ǫe/i6 d)eѢGEI !O~3?{v,~鵣aCb_9B/(=8`S$9 ]dߍ{w?O W#|h]WC`?tr>SCh ?eHDj["WgC5#$-nUglbV+ҥ^ARݍwl{~8< K(\쯔LA5a;Mh&iN"ʰv54cs[0Ru؉5d-57IK!0>!_Nw_!bd:%BU1P20P&=>{“RS_'[S_0$P]&9 0 E{ 40xym ݓu(Ƴ:i:_~q>={ i<|D@]SߪznZUǥ}xFd (촥38Uf؝FU Qdwg~O187YP!y& kw?cHы?FďN -_d[]5v2$")JBvJW6 txC{fs3;EnT#ePPs.Z :>0f$t Ƚ S.G+`,ڑy_"@}&D9NN'z9 t_Y Ԧx `^3Sm-CS%fDхazS! ! ܡ;ךj֬ݸ6̖Z^qm\L-쪁Ļ rfuX[9k- T .K$vm㸤]hX?ŕGׁAxVPp +FU .ѠM%ȩ>|v!O71Lk7<|ݝwh{9^ V*J=`xf"z3PL:^)2 ]*a؛`YAox$  NǕX5~<0[rH"=1G2ܓ b ݃%zSeB ;Lҭ7ΩDi} \rK;FT4[Vw:hl9hc2F ċޞoca`>J`qdyYۜ_TJQc5qi鎩.vJ*OE'uP-e$*6/"'YGR]8{ )ހ`euTjZ`苞|HzUwirB{} y c AFqwB%l^ĭצb+a{ XgŬAgw)#O7`O{@)J`by}lnYY*8g׽:W mFol%u+C FqxYp%$: -]Q 4"`VGm0ݷŹ(#Z@S8e X`>2*?]\?*e2,ʤiV,H M(G Ƀ$ТڗQ'vL<'=U Hbg-0)}L"Yh!܀gva;%߄j|+1۪!-OTY`. "hg[ăB (^#86<2L.'E!(;*56C~3vqUZTeͩZj#D7`|$BuBP (%cdx>i"o̼]sD^Ơ.I[屩 k_c:x\j jeO] Kv=PᙞT'P eif cVh[HLW.!.MuqԽZ}]W:x4b:̚/{,su\Vqճvz;Gju>C[k}he?{VӬJ!jN[eLs@;ť# a"YyŹrܵp' ZV6-o mrWHib({~+YځӍWS1zʫB)|6_#./ lOR/p#$HJhWL+4f{ux~)fmPܺHrt bS RK[7:.'yz6o"T< \myͺRt,DQ9+Ay+[PբQ1|*dhFXVb萐6H`եmuymKV7mhњ; [y'IU2%KV.K̍󏯍s(W-{趱U$E G\j'Ir֧J|Ly篇-?V;EO8:ㅾG> +B0d @{},=[W9@jXW4^@P H:3ZCOS>(y%C9v}]yp/A008k4Ф7w^ibZiW ¡@@1&g 4lE)'~"SQl+/^,5A{ŨЗ:JQf?Cd~NceJyNpsN&/M&@Sڻ40\ 7QxPB>6EDHRBOEwfy,hΨiB~4[|[(T6TQxgbCCF5B\Cf(_hr($uY|[qOG-K# #-^RB𨜩,ܦGؽ;\EQGsWEL*fe*Fj6s4^Jy`ͻD\f $ox6\ѲDQ;]cc)S&vv4BBPR}8$k vX5${Dt' I!|]ދL}qNo=Q:H5RJȥ÷ЮRhKC4;S=Z e]xP5Z@$`چ0dc?V oѱoXI௬XB"a["Iu-^ɳ+ʝk9mF3*r#O⛮ŻsVSk{MKk0$R'xU<fo mWFc\ DJ$}m6{j9'kʲ 5_&m`G s@ڸ9<"6,K]3y'o(_K( Zoan63_y}!џ+*ݯOGRJZ:5~Ocl]6tx>6pF[7ݨ_~E[hP# ηh v2?V\RyypB}uS3?8K ]p#L E"[1f"\E1x eRg#:uꭿf?g8F 񠱓a/ܧ_dy/7kN6D ĞSM/o]ϗc Kן 4Y~d@W ʩgX#/#7 poWv\o`Xn.EΩ'έ5:C\y{^ G|hshZ:5y;~tFV}'g_8&'>k=_N°˵f*k@Xq/#(8 =]=Dl4Z5  H e;M@#_0_ ~s-4 MWji?lT? n FwJe3^NpBIHqgka3;q6A+sM'X81[ᵶZE]WG.Ko'~f&`%dS68 ,^l<`v\qUU`RP>,<`dw&O)%MO.*ʗt&yLsɧʯpk*&~`[*PB6h;/;egpo%|KnQЉ:%`&\fpc3С ϕǖGw[gB2 ­k`+LC<&ՅscMu pFE^o B ɴ%eiAe*-n=˂ߌx/Wh_z||I/gb* [B`X%"cVgH K"6Vyً#[ Lw M 0'X FB#$ .cĈ檿k> !#eTwṢ.c(7魬rZl!AFzcK?I^PAʏ+=iȴ]{RK~*bc쵉U]g%_awP51l[6y%ǷJ 4k Չ86jtÜ96fɻ|6.nҟw ݌e7Ll:֥/6Y:&ޠ &"Ü{sl1ܻPRgD$`]^\eǖ2#$00UuVp8?̄u ]@KU7n7k[ɻOi ckx꺐,#^mEσ1ݗTE*#cv ߞSWH_*P^Nrx8o E:Ėq56!ǭ 8ƪ?jpdZJ)f %M=t$ zJ]PfO(o8r%bK )*x(?(.f"*By4IEjݻxaZ]$7y7y'/G @ƕu7w)dEYо*qywE?‰I}\}ŜTbՔґܚGp_aZ験jtAXN m`CV }vyF^Л<."|kmf"z&X1 hY\G X8>m7JO)҄VO: ;VrqKTA 1RS8ct*ЀkWo+zfaL8`yG{"7d(N*=i2'Ճ)Xᘭe4WCG7w|^b(>=R ሙaY4)Oɔ[Fºwqӎe݈+D^බDTxG6}S#bR9]㑳rǧ1';h eƮX>;>5-24ZgnM;YYIVSH>|̓s.t#")]'{tsAc-+6^CӷCmLI6|JNa ˺ÐhN8V_an1va)Q)S],pØwV?P>jH $3yUD"xIgϴ noXh>G |l:Gv[d.nfS)lG/rCw!,1$ͱ EHE/ Lت%ֹPt-:#! 8u > =sYĎْ!tϜ Dxrg$| B'w' `ȔieytWv:銛EZ7A_3`K6E w4&?Ɦ0J"G87@yLd-\Krtk?+HeBo޷"q E/̶fDQB8tq\Qk5M2yT^)H[Ej}uc(QF*+xu_W|צ㟤긩FoTlT@|vдÿ@ > )#|"e 4^vrd CJ ń$z]h|ײJг\tU[YčJ;foͦr;==Jv4 _xUf%dDoG 6+M\ϱ*5産oEA <<7H>~QSWE'M")H(nEub^rC}sbwAcӻ6n^"paaOڭYn\E*B9 bb5pr^qs_ x+4-`?=+̤=d%Gj$XЏi8򋅄 ;aoW'L'JO23ށP"ю7lv ΰtzvbحj& F`Hj4)/q5P*s6XB=dEuB~OfyV)6?(T9…:zܰG7W\em7ˑ1*+R)h`ph˟/+^NŸ%<8^bZBjLB2Ԛlm A-nR|qeV-M#F q?s;Gä:SLk| Q1u낵ȬE|Yqdf c5`L9 Γ'1h?kf Syr}se0馽ݩOuß[vE׎oj"7)?1As|A Lc _Ĝ*?ՁSgSn ; kH$ڙIæyo?gy4fgѮu>#0B(d 6+j+GCJ-ʢlcai7NEoڤbiŅ0@Ł^jڈ_e3f6H&ټ2kV^m6%QE7u)`q}HjVSyΑ}v ƍS}U6f+ެͷk:1ǝ.: ,MIX;c`1GXAigpn1q[/(V|qCILL (ǻ)‰[.iyQCZ0?-aRK_;/gh;xbח8*K{j䊇X`uߏgi(l;1dtK:b ~682Axq 1-Q\W}Ĥm8 m~C:B_Vs]P`Hpۼ:!Tm :1H z Z_ɩo\B˙d;΍ej Mw+5lt3E l^A1lAA)}h)˝Y[[::OG+8( /Z@#)iMc2@(;'/ ^vO湃@GT؄dWW~TE+#x$^C{L_6{BӐ+P:, uORSU#Z\.Xr  k'-AnQi|LZz^TE s"( TQ&<$.s2QYxeU׃' O:Yod<'f}ZX1B+ٗ(_׿:x ;>qUDx= &GB4k;Ѿ UK3zH=%ٍ~wa.N|R+%ws튁0T[aa3$ŷӽq, OuBc=ޏnڳ]ne|TWnKVFm:dǔ;-v~C-TzD򤁥c ]4)ܫ7RWjT-g]`Ѭ 5#C^ q~g[q)(BsRz_ WpH LAK-JBuߏ!f3_ 0Vr4Tvx`04;iknz:' )$?-@'IͽR@,FB٧G^0&1dXQmu<}BuTbrkɉh<̨eQ:6,gFys/ 2V+`H$[:[`K_4qmeP+6lr{]_/@/tdw{-,ea Ѕid5$GٵrITo*iێ-2Vm'IQ^lUFG1By:b!q00gJ}@~yJŽC6wwH*mb pwv{Tv^n4<Ъk ddX pjI\tg'v HN|!R?qw|Ұ}J" 2jᙤdtTP[t3ئڑ\w7,]D#t=yϘL{Mߑg, j>_o^*:Qp@aTbB㢂.ŵpƖ/.(bYM9lO|I[yl TgÎ)ƫ=Kk0r=%P2+((_&oDw1&&=0~TDG"¯'rTF^C@^~9Uwpѷ\l$ 'M~).Qk{{ ɩH\)>YIJyo>Y r+%J7kl8aF^'rOd#oWVaϝ$<ߚއ^d>D AY.4 >(Cy\w5s-Uilo]z=Cs/V?_ 0үS۬6U7P[*$~!<̀,'m{B d {xf:6@!RÇlmGVˡ(JkkR4\%聂s}@3u^–LO4S ]ѳ=z |#E eLyڣN!)Ůwfy|5aK_b:ZFQP9$=3]Rw<i1Q VSR,*Tu+m&EpF!-%z2#9^C$=2Nyp<&r&z^ZwV?ﰄ"Jg\F} 5^^97w(EMn:A5U:>`tˎ *fXiT7'mPϡfGo߹,|gVM % ,kV׈暥k\~(01!tos@"[ޠ(#I Gճ.[a0BŅz: 3q&F".ƀ(m1T6&\?JORc=oNT<_uݽDHB3L~yg  vST:{*_V{G_iziަ(C/6.%Ivq}^1F* ́ ]SHZA^#sLLe$Y İ> `v23&t $ţ.Zײ%nUﺸbx},. Ö*PDA!ȫ r ghAp0/P'}t SA&*Cp H DFئFVO^ =Tlw Ɍ/ebtB9E%60؋r@v8;#ңSV1}Fǃ "vQY^rvQ<n==yk[innX-)(\e)(َov*+ks[MўhnN_1vj&++,`hgne]8xAiK4EgWRpe:FBwKu[V}%QN JAORV"+ji9EYo.#And;@P͈Θ1 *WK$oXW\Q㼂-T.[GwO؃5^`n)ESd]NDwГf6 ܣ=mIFݼteXd1'̟ee$@2W*#L"wend}Qsdz8B[.(B=ؾ 2le$? vNsێaSEO`I0P O9\z3(3ܖQP~*v EhIH/f8 56Ax VT[q،= O#IG9^ᎊwqiXШ}*p*Gs_w4_nk Q@7ץVވZ6^u_0ݔNnSFˆAtp<47.24G](Xg^SAA0h AnTq_W*h1ae|)F TFϙeim =9i9 [YR/*ZDl/ Fu,*ǞU Ja!mA':B.x Jkb= ncO9P#t:4J ȆzɃg:bC"PjTR DE7^Իr?KgTN,ocA?&m4zvX1*4OciSj Mil2 xC$Xm+xX6ml>f򸐣K1$|: w~_[?^|jIt;oگ쀨ƊB`ջ*ccq=5Rv b5 ͯ})ď bzC;4 fFF^ 3@A3?x)r2Aq[NFMr a2>/?~Re?WIՁ Z:0N`w:F#2Q# |Z1shߡRk``)BPxO+J˜{HcbwdV @SS~ؓOD;,:/38pX@ʨkN. 4Y]&LY }P3/ԗ4q&)b\$Mꢺ|Oۃ%xxLjϼ[`cO|8P00 KEeVɒZm? ̛nm׬Xhf [9VaO@s}gG#$$\mK 㔢:/e;U&Wסwq97U Px~Zg[ "/ ,aXT+PISsP_hn9ɸdemn2Mx}żćz0u/}/i旹3Y0D*QR[`Q @r$#-)U]y Dm * !(΀BtAe1SfC0 t\VʎVIjRM?p:r>k2A{spyQ^lToT#uޠSJe#U(y3@VS"_h R~+ B~_sC-׈9;y%G/j֠'qNg~#E!ohxڃٽzP.좭 ¢q!M\+ ދ)\e&Cm*ĜW/1C\ x}C~U㚶My5m.s/p3Cyܺv`?HLߵ7TlEQEP2䴲% r:T3G(*9F֚#Qk[4cU`;yX6ݩ8-D*4B81?"E Q9|]*%10 "b@bq3d@^_QG76҆l ;jރX>+\\K'*c;k9c8]b)a* 픉/fI,p]#PY )k?l5uX5DZNЉ ޝPZB^MN~tziW@E#][[Ld RבmDHuzKy>Ċ*59,-^_q*r.DSwߪ;hJx,yp鶢(U#)FL"\|@y8o=7AJ$\ m+@E6+6s\!Ң{%[.Λ:곤i{;(r_rZRE@_b@t CEFle@G?!S521 yyﶎ[q6e0]9"`ʦcF›eRV+s#N2߹>-V|N(pŚpL0+MyA3,Je7m,BOrN{Χ5(-ȓ?v}TV-/SM?_1X,`$7 5,werc,t(+/&ٲ,7/SKa9קԅi]f4u Dvu r`/R0xu.Ѯ|Әӊ\|)rY:%z@>rƁʽP "n ӑs4]ḲBL,p%ҧ7ҜbqF//Ƙ%\mt'8ꡕw**`l)=FC:|$su, %`!0Q~RXWO4LqCH(S]ͯ= r6#N}Q8d[S|7) ezۮ!β{Hv~C'N=B;m?LG:",VkFgu&5ȫktƥ#HUϨatNv bSʌmU* |\ d߰EizՁy]5;֮M||b}7goR5(p3Ou,5bqp{{H؁'zɭgFs=8 څ2YQ'E׋+J4:1TDwqŸBES]=Wv4ȦuKR6#[I {/Hi:)x]1~HnE@˶e*PPF wY}*$Cg(;ԟ1Һr ŪXRpxCB㊜2G|6S#|߿!y+#8yY8,pھ` ^7R\2+-jz}ݛ;4pHn ^΍اe?>4M2I^Vk{+w1"ɀ 9u3%i[b@K-Lc)) 1JZ6K{~r*zsEb2{܀3MxV͚'(u;VRnhgلv8:*`bAտ*l[bq!,9 ǫ@0h$ 8@b֎'`B b+duzC ~STko&K\4),떩_+,/޴ ZGhc;o8j H& bkkj }Wq;F#"iiУ@}yZj8?եGO;җEx%dKS.2\9˘Unұ ۲O7MQ%/M۠Cb*`pr?)Oit[\5'x}4fӴ.ƵFۂnS#{t0:4Qeh{-T (HA*ҲgwTKQü .>N1xe}v-%V[3ja c6|{ia`Ćm۷""ue \jWm'DPѿ)ĵv$%5Q$N +^w&6}:_`rlDJ->q&ZŶV#k}@ctd4Mmhu%["<+y,>*tkCb<z,(jTOP ~`H9Msz$iF<~. oyAA58ӇP|` rVǏlcqZ~`HʌzS!0ڶ FCHRi%/f9+5b#2Z&lr}>-H.xP9>@b@?S3d Uzoyjc:JM1r៥ⷜvs4|kE*r"ݜlЬL]0 *N5]MghN|Y$lpWȋ=Ao_kPY t\Pmg%_vUUZC ywXct TwJ:v c?rIT3D瘬[ BI[4uڥ_#\e"LV $P-ٯkɮ! bl$kԼړ_>.zo5}|Z8OE l\'ČBUV`鱄nE]!ͷYg Eܐx﫝BUԥEl5tBwlB8\Mf1➶ekm[{VUA N468/y%ϧApR)&)3+_ ˧IzBCʃTtoɒz]>O1X8Xyb;pL,O`PCRrFZI!)YQeTT߳w+wb !"(J>حsTXGGY5r5|@LBT|S%:NWV1Ƒ;x^_NNGG޹B$UE0bҬyD 16qMLio!2,06mCh fT$=P, Sy5}5UំIYHԳż$I|Z'ܣ': 𕕝 Y ^NGĶۑlB ޗ[TV Ij-[sdWbd[ QՈQtP=VkR T'&{75h'ɏc3O*% ]̬FbpxW* ")~Ӥ=K~W)7?Lqs27YXBDX*B3%UglAہyLjg؜qt3t`)E#K|GKкAumD_?Z@k2fE(D 24y?b#ȣGS+v*[0UY踛FtIW}鲭!b"x)*Zy'ATd'U 4 o#! uY_YQ8F;< _#ygBq\b3LB5zfrWl뇗;aՓzoQAgK04XcB&0n ugIR[&A(O3WI]qcZdg;r'@&8h+zi "7%Ǟv S&`kHSS֡Ls6icQ3pQgYD=`ׇy #Rm2jSSZfyE%> +Q i5ی\?iJNLOep)ej. jN"yA  4}?~G6쉱r/5Pqp!fu ٲ"byߠ1O$L*.Jir`h#F/0֪x:OxCT rk݆q:[3vxqjFT ,ixt_k d4Th'M$%^t9mg9AV~/KUHI#6`u}լlwY q@VdMEI¢N$4O6;eVݚ8֟-{RVkH'!?U$+sC63!!b()9`ufq 3Xr_;9 `UM x>^3ϗxLI9+|_(bkZąrAM2L?ӶZklmEDzTnG+`08Bf%翲rx&G`K{,$q3I^r`Kub sv9S|IM2Yn"߂' *^Ýȟ p4^ra@RfuHZ/4ا&))Еh&h}D93e*<`׋\.F+ ݁gZPs,j!Ak2!o4&hTj}0V*g)JweǶ>`J[dpSۏKBZ0iȐ@W <+acU >1iOQYQwu8[fOG |(5M:{/e 25>K`0M~guOiޔ~]WI`yWJpK_` BFgR3^ mC~HppV  ǏoֿҷTV+N5@k~RxیO@1XH]]cN?|_ثI~n،?e ASoM,f֌WiHU )tk=m!ty ~v$WuN9F3<"nl>bPi]g76 q<M&`Kb4s2#.> ̯B)Lozeus (ḕh9DݚX( n#,Ko k. Cc% fNKq^ʟm<I5eXqԝm jԺxgd:iy\F5 ~o:<#:o8m21IT[vpQ3r'NL"(U^ 7[zg&o[=ؾn wmg[MeX E?I̝>Z jy-Wl%Vp$M.{^ٳ2c;$ۄW*9修5`Y^1:Kknĝo!D4ڡnۂXx.E|JѮfBs? :w4Ad) 6Bl|,|fdZ¢uuod)L'+.&?'3}:+Y]V.`mkCCrbg̒ ΰf Js!p)YRiH2F4BmON`th2Q+Ŕ\'kc5rI 6" PkLZ 5tψ9*) 8K]~ 0ZPꝀf[vqO7:摖GQq_@c}fUve Id=UOV{Aed5s ws=3fz9d! ,6K={zB||`yBd6QޫkׄAZV̉6uU~WK^qޔT5cO?Gc8waA]l,c7Nҩ]/r@01&hdшz7B+^&+kC_K˔'nK$cjwGh撹> 6/Y%U.xWT{ `REg=s8u %RE}ө4[B+EW,͛<sN |6j_tw BN1, u0A8+GKytb4Q:ۋntf1YR* GkNgS:Zǧ@ ?S9&SN=6-@nRNb߻d-5 ?meD tlέc`SREa )_J̈w\t77WE@֍rECRh̊Zh$:.hYUu/Y)I=[&-\[Ĕisdj{7#❬J[Yr %Vx9n3`_<|{ z{?Tg)a:JHHgmd\ }9mG_аzĸj$Y\6iR9YlkZSrSqZfaIWtnMg;OLyW=KưV7׽P fTON{ &ҍ)^L"oZY~u{]!2 yb(a-#r>'H?Bg Je*{-N:Ÿ,Ar rZͣad 쿇xH#]z˙ V %^4X7-Σs$PHp1U|)IEiLB3)'4̞LmTܨ|ALSљ] f?&l6gVb_D瑣#ރOŘaVCp'cۚ_BrLhn]xxnk [Y\D!oZz"[=Iӌts%gosˇ V3فR6J?(7jAQL /Xz$lͳ] WUlV6pwu|G]\-G$:|H+ƿ|5E:HS^D{;`b5/(t8 䘤iR~3 "՛uKr27|>Z'6i[Wpg)7"5 >l4ֈ3Lu쮍a!Ld+H}!R TGyӟ)Xş6ݐ\HggKľ#ӭ{1Ё=789x,|x 41ⴑ 5ԁjscH`8hzBG{ƙ k6} !rܮ W[B_:#Yh~<%X+23ZC \+b9J tQԕˈLfHnAMjqIZpY ]8'nƈ@/ 9a]} >*Su 22ڹx}\pvd [%e^r,s=C3 k(fZÇQῢXcvM.p>6h5=n4xEAje?6L J5UiB&5 -k˖g&&uZ ܲm z%(D睸q=H0pi_2hAvc M#Q7іӎ)KLve40]Jcsa=;nY+1̒a<棵<KL~x]SVܷ<Sj 밹h 18>жp^r}/ S49'Vn (ƪ!Q&=im\C/)AƖIL<Ӳ/a/|OX[uZ(7+ChgV ,B#[?2%3[3g\f-ð{'g_nw'm)[eKQ)D'Q-5:&R"40^. ;:蛺dt} /}jXMMJTBʕ'VUNXos70OLH神ڌ>"ćWB)HHq8WmYYef3  -42ЦPyTã^u_ tRR70 R3wL1f[f ?ٌnTmO|+v 2|V#jͰ5 %ar͔=1U(&Dp~.*-p٦!XzDu5q-a q:ѧzKd]W>S_\{ hH:gKm"pe(̀1ؽppOCH`,< 9` .` ͯp_ +LC3+$J./ԖȘ͉fԉ]TF~Mk$_:,UNp!æ y˪GL(zTB뇜c)p],:W=)J5A U ۋ"HSf_Tz{{P$Q"TExeF4럇 '$_+3u|6eSyĹ$7emUO)jmZ vO̖".49=djP`<7^i,҆4" |įHjZ(+SXr=|:0%/}W6Js#`юA'c._o2u>N:RweÚ%[H-?>j\P}~T#\R}߁:o ]!ʶLG.onDž5o?7TQbxz5O~Af2)]բK&nB$MK^!ǜNf/k5?uYIp/+' sm+KDpBUVvSۙ.;,#`:֡,Q&WP{/z x6:=Zaa͞2xR)>kZ]?' YMp a}z?s^l $ԤnVnbC";cZu?a@L l*Φ/pLu§Dt3`_N[|DFqAUFAoWj HtW" -3mmLym5 ʵ$%|ԁ!u\[)OǢB<~"eT`àIF3F,;a~6* 1Ebx}]XU~׍yxFMyEۿP%,`R{b726XITT&K)+h ~8?ӮX /&E=ȵDdboDB•Rp5~A)mW5Kfr| 5%2chwjOERkaDUd^˚3럫֘hH,d"7R2GVFY pF[ `1: !TFLbji 4y!3EkN,Keހ&N:9)tO*t1XB #HN9,`൝Z[3o٦1"=9b }=sAٶo5}Z5"*iΊ t;M{Yy7&*$FԸ¢7֎:y-x*jV@ed  0^kH2F;o: خ+ǣh3Q  ԪR'fֽ{(+Ad}pt2+]-wzd5ac޲|ux>_i.BxjBҿwnjV"#.e0dhĥP_#>/ub@\a6츏=!gPdrZU8r?Tll졘gn!]#){e4B37ca7H |1j ȍY@=!'n :Dj/{>sQ@s$e͐vFl rS*ea&q i؋^`_!⬱Q[V-֖09F*kaMf;w7;Z|1Y1%O =wulȯJhS͜6&8GE7;}`)'ћDY*tw1R"xh9r)n]z)}}!=S~NKPSeT, d_+P\l',ԱT5";=+%OP)Hp '5]:#](iF|RTD6W p*+nu~Ru^> yC/nHwwŋk6GfU^/5}L>Ö=gōi+y)\!7AR >4 3v LGzezty!s1=^ 8"GLYbDr;+:4#L>xy4 HhyD%>5S˱iőQS]'Jm?>U堟m[鏓p8 hA k'Gmkdկ,ktۗE_E I+>=YX&DueS%lʹ>:H*+>Okl[BK^f!÷ˏ5Yl=}@b7hU&>oE{n1L cE5O&pmKиЧ3ge,Vh]$eqmlt֭lW{ 'npb꯿^tjHL*s Pcv-.>D.P:vI7hp~BD 9F>0ix6f+S­3"*!hPIE?)L0 1ty\}&LlCa-hn #:S=S-S'yg,2Nqay.ӕc(rc"z | 3.94;5wNz+Z>C"/S{9uGY ^)bK3u>L>w#n)^Odc݈Əc饲Z$IA`eeXs068P2۝,ɉ4q~9jpȄ@ wira~uK퐼:":ʴVψ bWTmfL&$M(f% v(10 ΎLn>w_@ ng복B (v@mH?6߀UHw ]o$QNgc܋$4'Ω6+ϟngGKȕ 蜇t}Jb.xQoøBМ8>&φ,|׆#YӷފE'0.媤YnXa\z/vg04@4W&|/wW )[^R<$q2rKl>pο31ӌFـ ,6863a'Vai4Lߎ~5`u;!sC ݢ谯za|Rhojl|d &۸2]VL:D;} xc$p\kbvf$ L M4'kN1pBB‚cayD#%6<ɒG{+m&IYS.Hۓ6_,!Љ Sc^\%B{kcpiYOZmJ"] SWV(Cܜ ݐJ56O!09qu1goT46Mw2׏J<*j y1=`-kyo28/nΜ> VhH~Í&$4kypP _ߴC7#ٵKva$юSG&UUMiT7J!ga@ ,ac3Ry։h 7O&Beq\pnc']I/iGў?6E/jǾCXNgM̚  Pc޻1Ec0f!y{z,\S5h==WWc479scV^$2}.PKuCKƔ =I+!66/e^._>blU) s%沘g7WV)):+dT\qY(3֙540"/We儭Uc]lO.lD7wLW9\[O&RLUcϒe: jkS/B32kdtU$eE\ݱ(^%c[.xHG8ChﭱN WvYBbkGP]ե !ŲbJ-^=~4khYD{tIGu( zD<+n av9F}v3;f^7`Bl'),h.nHgvdZiguPX"<㙓w)YβhSb5p=PZ`pMTmfJ:Ƈ'Yi^Xτѡi'nن w:FJ2ucBsoWrMdM[(6! xJqKx6q|*8d@WgևKrl]%R;5a*Dk~hQrw .9샾6t Tw"?l64F"2y3)#Y\{7[~C>ccܙ`QQ²|(ϕdD_'~%K ^ q/TCO6wRtH6+\{B+SL/ p75pޗd~t|I ;_ÝݘOvxX[3vw^튟s t9,طQO }"e|[³C!"- "=M6$'>Af! a2Nkۻgme랿7  i#h(BX& F&يD9lDNTaůgz;ÒS%-2jrJ!&-@Uڔʢц*Q f(?2ZsZvN(KeKf/@ د=RRֆE=Ю,# dFV.Xd=pcYD!X1KoؖƾTw5-[hO/$;!Q{KU3^3C\׮U"$E^b6C;*w]~vYzEI|T^ZK#r=@hkf F39<Ӿc{ͬBetD7n9b&aMiF3ʍ5vdq%.?cnO 0Ha;eX*#GZ8IWʭɔj)qIv*qD)`|[nl-MsyF 8}[&j 8LHfV1VCd}ME,T&fGl \6"i4ZFwy&(lݵ|t;F#iUBY|u7j\6X9-^Iax?،tZvt4c?,6ynYr/D#^m9@y0ߐ |`^_߱j2LT5ӱV(&RfhSۭ m>8]+{]qL}PՍGɛrM,!U9xOiJ)&f3Ӵ$Y,?/ւL/ߘeaH8=2ɛ5 wԅґiSh _u c"62+%4#(^(nSϒNmGB7~I 82ЪaI2wfw&"v+V!^T̞UsZ Le dHh8BGDe@ nJ.ĀJדlHu, {#;wrL^D~o amG `Y^︂%.* h"IԍmS|[PI!D/ )AjqAqc-pvn+Z9hj'>Kkej?ůa!2E[EiΘZذX64-i1ormdTbnP'DԢ|"['(@⦆1~ Uɞ‹>b~>᪠E,dꃟvύ}~9Rcs\==LoEP>P] m ސ]Q)ZEx4tɸ|+8ÅRi߇m ;L:;#cu'_oN#9x7A\APm-&߆;NW#=#"i֛ c᧨VjDȞE,?]">rZAj}bE`tͶS6\L& h<R>)ӆVFB#!P&x[sj+ar`yJHLzR!<Șa*Z; -x_8HD |(QڊAcpVPh8$񩒝s\S_9eAgrRR$ l[#EjYCUNӥ*0O}9r1eX"ݹ ZT~ȣl͉k:As<#`'ծf- L (2JN{ͯ&Ӡ3zonr_ozI!Ņ S6@JY qP",^nev2@h:ȑu}_zI0gBMXũ߯JݕG5Zƒᑢ1ۄC,w).a560p*UZrG'|EYr!B3\о;f>}{nc c@-&;>*kUc(9xnF׍-6^v3s4ZrpF859m~ŸĈ`Xkfwd/i5Cqht*,F5rGP/ٶBVFG%%)G9Ń[Bxo42 nCZf9M̑ϿGIKyz/061˜_53C/O7 pTb?`OJ#9>~$pi!rlRN*peq3v1и3X-XP.e`>9CΟ3K65eNoM)o*pCڑ5g{KvKǺo`vFYnId58Iۢhmd},jo<&m#գs J:1Ov!"Lp$_sBJr1g,v=Iz&ہ#!)(0Q"^ȴGM҆sy*l0@/*Ñ:Pf?z޹t,L“U ȗ WA!ug d>IEUhWZ&XU|e]H!֛=- ]ZIIO[Vl kw*FGҁ;(ۄKF 꽑Ds APOٛ 0xQ!ٿa'"Zx4.a@Lrk#)e%Q Sa!dI Dl|(Η"2A &wz !KfɜqxR˖_ Z"$E,0q!j}k|**687q$%Ic5hƤ&5au2 Մj)$qy%Evu"z6\ s Lq_탴Ӆ^ 8)7x^}g=ir8ېg?jYdYHTπ]Ҡh{֤[?QC4l`!lE jt pg<67uNV]6] (s1 Uھ XXʂL 9+)dۊ\\G<_'hɅr)g+y.W X{tFbտ4a`CמaѸ9s"d.j󈔖@FOEPG8MV6S)dloS {lNE!# (' cKۼb#+j "dtиAJW vt=n9D ".<zyָOC&˗wA,CecHYC~< Q"gE%UeS R)S Uy\R h% >.-.Y|,bs<e}s; /BLD%"|ҙ7]ФpN6XS[ RfKVfJ].K␇ bc7k& "jj݋Z(@C$ѮɆ܋*+IV|IjşjLN_ua{[p2W545]BZD%ݦRᕻΆ!oGؐ[^  6'W2QIhߓRsPBQ"Un7^r/]hkF %tߔsyFl r7{|r$<&>+T)*HMr/V >,B_ixA3E-L-ykD6=9gSɊ[@H uV6 uU/)!!,PzK9G`#RvErN¼ 1#YdqrtM01{BQKu9X\rɅN^Ox xHd3N)D\ ztG52=FC*FN9dueWdsjo;屌0\xIR73xH NӭZl}Ql#]cIx|Ƌdz*r+_|ٸ;IM1dN4O1$k4u=l>A= )g.*ГG?vJ[9( .ItzWD}4^cu LJ%2c avs@;Ju:F"29JOi.8z NJc?HI~[oMB *[*2˷.jJڑI7=oI'͠LS% 1X#=K`qc>Xt̿u~cxYVA5kG>ᐩzY51¼i7 G}Is6#Dk B(Zz/Sln9$^M'WKeF>" BA (b;{*'O4dPPT9#"%.Avtv&* cޭہttS}jS31fbh\mW;vB*+C&dP%RD.ī"mAo^q ~!ʚ11lL۠}{M]ޑqbE#qO_ 6ekR)[A+]=@OXh.ć9ncb|:`97eku_"Q >ƥ;y( ;v?I NbV 1,oa&Vq0+7A௫Q$hќZqWN߉1g w`{:C`쳆23[9t| |x1]ROQR7PI E=)"`{*wA#?XzpGPpP )<Ӻ?i³_Y^ $^P8]\KE~2䗬7"m Y}&su 0s"U l >a"2pcZ)>?(9F0to% 4y4pAN}1D;@`)Fdl5\+^M;Φ v&YeN],7V(9&]9v~ jbrcU/)C2зZ[߱h5o`a%[ZHqa֡xhȀC<}hJp۸e~ze/ qF,ήr:!XeS_[G:aa|@ȳ O5UvaŖݳ_^RvN`"M6?2&!f,;@BF#?wZ UT9E~ЇP'h,.9@za샥0HJ/2/1rS4*ekd+ 00L(Ega` {1їF1ADGΰԽ7M׽ [JcȌxuxYdD?8_qF/}JQL˫ƢLPĨu_ \42+SaydT"vU*FU%{"D`z.'䭼,$qn'$nJWAj*((Ut>I)#v Pd&rZz$XIN^²$^J|,5 ?T'=NDNV_\0Q'ԋ0369x_ʽO :D7>D!(Zc%!AP5rqtvyi#uWwHS?$}a'.>"˖ȿE(Iն웟B0hH#?6v$W -uTpZ/%%6pnqur8vv:P#GW OqPG5Cn"d iEb E .#ã(p3IьV?+J:[;"9X-㲖^w7<;'53FV/%uk$Kթ DC>]荾W0Q|EgX&{Z_ߺU5KH 6+,<\`v n\̇] |] T$ʻ[TxVI)x\ءqe_~;ֲǶl:S 1'lgCa8hB "ŞE$bZPSf Zߕ'Tߘ@ԵUdZm~~^X@+cOF3 |rw?e~(A.vly$9gaE DܿF.` ~4֜4(p{t{pƳpZ۳)?tq[P1p?6K2 Dl\"C P}k0Aq{[y!o/3Quג[%hia0}Êғ_Wr|#k+y3`{fMڥ5b>/z 2{^\T{n*.)Ng{oαnaO7M>G3w<|5d{o b.c;?EUjr{1 zרǀZRj%F&⥉t܌9nxX9>4A sFh,[3'ޕ ӟ5,`|SȦE *E"*P4Zb ^2,S[25^4=*^\*μjyqi6v=БsQ}/E.WC|[Q! ^Wmݕ2r3 k0OZ%O(qsV^녶HRq{кͺi&I }WǯGϔ$3z_|A"`L@LCaSCv LSwcn3s>AAqᦹV,;8%}B۴?hrZ20Td'Yf42{1O{CQׯa$h@f=,+ņW- `!o>I@Ⴊۺmyv0P8xˈ~JIlic=`#AFkdλͱVE)z1L=&pg JKK>tʖO=flm! 6ttuv]\!?[eܗYwf eA^?Bv{%΍go(9~N5rT.qeEؼ.qv0#]Z)u}8iVn͸ǐda~htd7;%ea vr^X۷Ld'?.e1qe+Gu8p~dl'09Ώ&IQ;`Tfq2?[hG"u n;j@&[OW 85^h ~ F}8:^Y`D?q/VKHDـyÝm`$΂Gpk7#Krw~&M|H̀(f&*&^T!O+XQv);Lf_h4)tY$.8٩@YuqETݹtW{@6!՜nɴs8$5iz!VqRgrSӋ{}i@NiVEI|닁_,{U o;N=_D%ϨY*cߟCH"<hꙅ'WT@S~k#?l{m1'h D[U]OS٧l$k Q!=Z`#"X?9IHkLZ")a;cwV{3+i}Ӱ݌Gvmgq> 35:/7z7k Qy7RW4w{,bf%ʾYbd)\i p%vḲ (E"3v>c!YBHD>usߚ=]f},lMa5AHtXJϣuH ҦUM -e8උ`)-fS3V*ѫhUg9&:[U 32s/6?2ZUY捦FM㿐3R̉Htƞ陝:~=ĵhk˝Jy0Myx̱u]^-\@m+ȺMzxXnNM_26x)=\~Xa~;2D8ŗߧj|\+FI_ .>\B 9@8Cz?# `L)b4Kle"AIfQw}#ؑEjby゗׏ _7`?Qpg~GX$l߄ćt(֮^ Ӭ7 $e^^dҩ[8GwgB25uR," gjљ4{~t[z}EfiQ14AA֗iC`F[BSCC͍ƹs#QL:0W֢=柺 %_̼ [Zxy_U!J%)oy?{.C߽ư x$'uIO%pDwa*:4DnnH|:YlRЍB4FOIJ-! ;鷂 ,Q.и#a,o3jVtfV4RE󴸍T[YYH)DILvgOXƭdF;Dx/0knz;d`\z $VMIPr_l\$ gJ542I"7].7USEm uTN*b) /B^DnQjJ6,˪nQ1뛋r~*zA͛)a/GVQt[,('EZC" l~Wc8u9}*P}^,P/?}ۯo9HK$ aNvV+.C(Vj6N$PvAsϑ/ jVボJHL+ }uN g>b+qe:nĮ95dh1xUCY0h?b@t;xк4LRC.Y?ܗ >`UDsI6ru:ĭ=5* t *{$C+$s̓-?_uDXpr3 S-:3d Y|OhfJQ6!ώ[PNa+/Ox|q Gj '>A} 0nelzwB7P8l.Wj/^=s7޲|Efyͮ)L8^s&\LZ׻tb(qXU:eJ,Z1 h{7:@ZӶFG+(@׷P.h0|*ӝLU`#%1Wm OB%ۃLjnŊn$G2/Q;-t TBJ6M f|@@Kubm~>DHYt ;0WO}b W> .%Ә|[{t{v͉R1VJZ^}pD& "S+p\"3/N}gQ39bSg$?,ȃݴA늸g_d%M vQL79d4Õ "O`[K!fh,PE!9ހMxo75+]?) 5]\v"=Aoq9;io#P#3rLkaXTHs[!̚XrL!85Yi+H='kq*T>M;Ί|TWPFvRpI`tPZ77Pp!e\"D'Q`  OpU\;C=T~`^Q9^Ä-@v=|E597<1V a!OmIY := CNldþW~Cˋd|R3*k߫6oY -22ȨdUO`f"0.,&#. EZk+1rAL^[}CX2_W>/*X<ӱ@QGhJi-'ga]V*>rtBK.-477eQ ]ͯ ܈]zѨvJއ|½ ZK.":9c﷚u_E6w-pI~}gLɧS҄㒍:5G 35bKÇFVtxtkW瀊-;Q6ئˏP&6ǎ:;-ee>ϮH_Ov.r (>!_~`~:z̦@D{2n͗tibo|)&v9W7P uIO3|X;-w <4UY?C!Ũ97ƢVkr$7A_s֚-/7(-$|Z?(3=RijuB6)^ֺ}t)1Wnu+0.=33b mʓPAZO{z9}d^"Z,hEXKlI<]~ӱlHl4p&H^fβj゜Sl"4eWZ2X1=){ݭ=Q҈jG^sŌ7|mKe~.U=m}׿WFE ~qc$(eOڸGHILVPfb&v ˰D){r tWCAζE_!P].~^zh8Z:FyrZxb,+a5De3tKh^+쀁c|-^{ô;ѝgc'cۯs4"SBp-倗Gv<Ȗ׮U=,5ҥX=~rb3X/HsZIp"sM4>6n/9gx%/5S}Uzʖb+h}uH9 36:v=uG#K*TӬƃ4Xjxm@"p=bmSD> "vqyO$|o(? r=$4)V"Pp=$ [O׸ط,gH>/?y?M|Ov&μfIJV+3տBdY8F˔mаB~*=iIdlߥŃ؋_UE30Q.$t98.V^hp7BCa P1ˡ 3mX, ܆ S3]Q/^C6:I*]xEO/%5]ЍX- ȬEirv}E"wtӺ]O=ID'+0ɴ-Gh61W|-c`K:!qGqCz0{^pmQ2;wH)`;^>ɕ_msI;;_rFYyϵ&r??w&ABsbbs+Uf?mFDM̷ŻsʗȪ 'GMNb4OO dxMbxݵ+$ԇ G7.|"1I 7:;d]h[WtRm k9 4|1Y q?4˹ "> hSL}&@1Q4;ʆ^ҙUqv>i~(#J)5g~ ?W#/zw+DϔIo3n` r(Ty ~0JA![= ˑLxp`䃳ݼ~9P< !:Y[ظ$` +n&{omgGi}5 v=72?ER-j)Rd*k$gM-Hkg%d\=c Ϡ[L5S0r\tl)k ~.دvQVf>-5=t'B-53_MJPMd:ضAmX}D`/дý]rZPiFeYpt|߅*m0jB*뭺Zs?MFBRv`TTxyT+I%b܇'k,yo :maYM| 'v<"4DF8E .YܒE%Q}q{$ݏxBsTln NPG?%kS j?g;uX Ss;MnF: ܻqíÔcg^ kƨ '<&VcSG>y-XI!vy(B:[pJik,Mnqx$X@B dO_%` \K>#&tA;JQ>_ _nes}ZB1$ql2g贇{B9xu:Į(*m`CR4ĈDŽ!~ dYWPJ]aqN Xk.0`rH#ShNqwsFQ}"6&a!OkW A]dSBs[te/G;mBI*~Ii44o)f Y)YMgWkQ5u EBiYof!ڂu+kB5e4]CuxSkUE܁ q&Q{0qꕦςZLX]_oSN{Kśwӯ,F:Nv"˟@' s #С,kWG<6-,^N v?'v#Lca8A&Z;b8oATfIULCGs ra{im'~d'0Y뎁U3&P1t2Yw $-¾3#bw궴vh־ !ff)Z΀Y5(JrpWP/`àvU-u6TW:< _Hc#y̟|c]KDS -'R859<,qW(w.uhQID.F=bٺ 8}R~E,i6J =J443{ThJaOaضLT}bN|S< hïDPzEoiN͍3;kҩzF<ҏB[r:bge _@7Lo]Z]zftPm!RpWtOEt--'޻ht } sP|1 aw'ʪ&%QٳLzC):a}ꋃ-kmR`Z2L]*'B]߶: 0) Hϛ>+y1>b>Xf/3A8 [4Pc-P˂5| bʻu0S98gu6+2&{,dkܨu#42C0\>/u E VOhJ_ޣ meoȃnbp""a$7LDQ"֨aN%0+f @" ze.E8RYuUL F_ܣF=wQ4K#]IߩF]sT@Mj DV9Y\ ZG󦩱@oP3~2J)g3H⢰C$2Y$PCMn+92VKg<cd;J왛u_>仰K[W'񄛥/:P$o *h"g& ^kUItKDWPđ\$l/qA$[{PqH~b WlQ;Xf<~u="?E ^r8fGXϲe`B6^xdjN2`t,8(Z }G։otp)li~`1/\a@o Kr-~JGjcs hmV xi*1.  CQx*ta&\fO=̵ɪ=! v0m!h Zv7}XoA.:}FGtMdl荖l+SĜ7q.g|U?'oGGXl[Rr],fdcL1mMkz. V+1W^cGfШTg9n tkSM7XoUV?NH5F:D$hunr1} &XjPOW'i,p_s\T+8?Eχli҉.=kpu\/J&owΧ sa#iSz_-ROZ^H>#5 W'2Edٍt43^t]20w5ޔ<2Y# u>0WIPD*# qG6Dglt85ҍ)`l$Orw3 >Ceߣ3&uQ毘:yc[E|;Htq!z(>b;lE:*S"հQP=Vg/I{UTW?J|`-"41VT=oE1VJYI@9epưZWT5  @RE⯤!0D.\Bq_:Z tDMyx{MR֥YiPid ,X Ј1~鶍 %#[Mi$T'1P'\$g/b }@t3%z֪zXnU%f<9)mtɟ7?ˣa(7 ­dyʓh!GF6:tSnͣzptt:Aa/y j;!Jy~"p[W&eo{`u(jzU(*[$x=#\gfUXXPvRYۍ| lLJۗ*T.-b1or"VF|.re'sCR0xR@GC,5н-6 %v{kS5/UK&T< u%ܟ=}fdD{Q[֔H&G",RCk2 һZ+3eu"'qPNۢ_tC7ȿr_d,6R6hNŊ-~ zܴєLtcay, -EG[@g0j=dPK,ytHM >$/]F 2bvG4wR)ޑPmb m ҚY@X*s?)045VD{U)ytUr09^Ǒ >`$<86G0&NhW~s$ `F_]XT$ G$*0K+ddF_gԇ{n\l:+~IIT$$AUhfQ.51^+[>J0<$<2I2,MSƂldx ~Z9wO]ah[HU?GIʨ{ ~!{ T_16o2IEƅHV"D015?diƋ7/0Kn(4ґ 2D-S;e HM<\Xqb`KzfpM`Wc~;[Ki/>4oKB'VYkuc:Ϡ%Z9RCWwV%(J~O&Y9zB~kFUPF.P͖ޕDA\c J#Nc$[/6vU` ]3g Y^OPZ|C T "CM)iՌQ o߶[f![v>9ioq!;P W ˅ PpB5.K-mBrgzϼҠ}St;l?lJ[g*AE6yHmfˡX82ĭkMUM6|Kw%<(R@>_P^^d BeXEX!2Cea!OIuj%p9&Ϙ3:aWjUoYfk$5hr, rkUb6|⽜2'3.'9芛5pTޡTr0=͋blSewyNcY#W㕡h4+yLƊJ2C+ v, ntld#oSiم?֚76M"vM9WdP#^~4PS[gG?欩'K::O"\}Jvw$,ɿ>p3ǥT1)aQ;Yͺ5a|Z*KvuN3* U2Aіa++Gg4 {e@@+J}q4Eu-h*FAc>5f3. `Xu S9 fn!ءz ІK;py p_qlhNt]@e}X!FC_1ٱ9peT]1i4o +DԎ&vk.gA׸DƪvDFr֪ryT!K<=?H^!\4 zJj5h{J&0L]Zҝ׉Y·ϷY "d}EoqN{|=G+9S8ÑWI lE[]Df?͂y1 6ryֶh =6]OK@cf0 r+ E4ڧ丹@6ʖ$mS]2ɀo+ Q@,0 hhoWƚ{m?-dA>h{7꠰p:#QWC̶L$q]0qH3E'~4<g};y݉ц$CϮ:F&GQ'e"" Ow/r/ag2Y2MˮkMW*GVyp .ύ&KtĥXe81AxG^DNUpm LfѦ\K%YU7&F$|f@A^"B!lXS\/hB$bҴ9HHVW"4\kpR|f Jz ?"$],=-?a}N bH.̔VWקôX Cu Xu^zywvNu0j6}"KMyeFS籶-9E;}OMssDi^Fm?iIpR4ޓ\{/G ,gO[ $ݚ(B yGE h䨁앳RoʗL_Qa)¼~(H!:Gf]An@3\khTϲq'24JIJ4ھ'}*sʔ[NK|~g_ѩHD/kx= W 4 , ?ej2s<((R/Tu ӝR ƈx(ũ ]Hel97<L֥3eQU'Cw($ ^+x)i+z;e-+tS w)4gq)1І㳟>/xgՑe yӕ/s7mVl- #MH/׹Ԇno:NhQC,sRFdD@*)` YQ;=o`Do/d"FmOgT3eO[AU>K)As7<~92ƶ0DB4ς?DܷڽO\ =" F;ӁҲɶ7(䇻P&$T .uuzk'$!4 m||Lf]lu._iku?.fKCWnS=H/YòĘMrEǍdp5 ɗ[20-[ 40 F'T/ATLvp|[BuX#w6NTa@ŝNE`Qr ! %2tlӰZc]}OΉ] d:犔n4( ﻯԪ\ O-%{۠UQ_y =B o1ߴƞq8,?$+56=CI#ơaEfb2B[wϧIhuqSzJf~( djcFn  ui>R|Teo6Q=PƅVN?G>=aMi"n t= )c>,Q^䣵I@$P3ukx9ol&ۃ[.fRt^=TtD΢4QL o7rD`ĕv R (ށ>`;U >op:%P1H#1XiS4*1Kgu8ar&J'EzSC` ϟZzQ!F';W֡w3 t&  sKҁJ6y#ȕ8]anQ'4K˛Sg6PAFuWr3/6FJ(N*N77T5*qDil ~ys|ׁe MD(89 xH^@ř8C <͆Lh];D!pm]f}BُC{[U_em{ߵÄ( _j8ߔRrޣb's7ۛyTlm9MA3t!(^Еfnt;:w4F$j{_]yrޘGPS`U{"Mς W SH,~%ɔըHk 1+;(r/X`$'ks~ tf0QxUXZ7v’gYվP_zš!h.ޯCɁw @I:pMyDb؁L4:-tqƲ>ae( zXa埣Aښd\Gmz?I6 ˁ<BGMםIݧ44ЫW4z.8+KOw_R纨2R7zV3y?o]Izn紗4%ӏ72R, $D+8d(P͞Sa/0)*v4W9+J3ruqX;e_x3& Of7\BP2V 1+=E b26igYi { XXbřAڿggȥ/A=>ψ`A˸ Ǭy\F%[ )uYDK/~8RnH8, ]gk Gⵄ h8i`A ;) |o孚(^F!f9''i]n*PE+^]Cf.yn00h1Zwœq3SIry9Hv#; ,f͐ɢNl#"zұKY☢g]x3_#6Y"D K˽ǝ֧}) (j 5@pu;@FA1i=3TbXʲ5FCܘ%ή:?qm~fS֗Ꞅ!0Hk ']erdr~BuѸja8 Tm /l pVU=JM 똿k yH cJ<7ya\XiЎniMݽ!%4o)]-61SLX7{.}J۝Cr2oyrY \Q}%2Xow-h.{&HG)=ʾ>' %'Q iv|^ϟr]Ku%7+qohG2F.Rs>O9.!W#lh #;^-4Ը_(`,os1FAI bw5T0;HP歟a_ZgN?#ot$4鲝zA!w}2aOah .>h>€8E^88j!~uN_%iSAv]^VTJ 0}To¼wI%^6r/Q:ev]nZJ1[6Xo"~BSqVUEcTF\I+TF&Paf.O7c9{;KeꄤIJyajI`W8{c@yf=p4L]jP$8ś qNE 7V[:sy34U;jB(3rc>,w>YfCSxY.eo6!nR+:Ǭ~ 4|M^QĻ0m̰`K@}4/}&ABi C-a g;q bu?& jT)q7p2<~]hfPZ6\2u-o} Ye1kk5D#ܸWSKg P1.-=kLbGs TOvt)Ơ2?~Y"+`BL]֛f^[ɧY"ɲjz[Aݲ\_Yh|j#z5-ZSpX:M9H*?; əS.b>WFc SLv[BZ~6D[K,]NMA!f c~QW\9tlLp\أC15T'7J IK3Os?D> l$(9حۘMֱqoſJAJaWͶF{Sw:4b)ȴ\0.ShS\tT Ȝтܨ#:C_Le36昃B )aIg/0Zئ~弰ݿ! [Jl3|jxh:mj g8ovi$5r p65ؔ:xr&gB#١ʸFQt θ_TKf'a7#x33NrgӾݝ#ѳe@ăL~`MGy>jrgAז(tC;_}fՌcmn%gAan~=6xuƼnb1`9 zf!Z:f{hbZ2un=F=)?s \ƔgFmTQ:hŨ r#ϢDHR+S0q6KԽR7'L%VL10ec|6>K%/+N'?nGd#//ʙ*g3}dNRz)a/9mKbu'PD?;+P`z $iaѽ>/RdVu2;?8o 8->i~-/K8~ZX$/t3$Ҟyׇ5~2 WQZw%~/#p9׫,T187&Hc3.%W JU|G]Q_]sݪ3FPL$b"'w$mI]X WǛ6`g@&ƾBe3ӄ=>1rYc*xutsՁkѝ؏3ޒx7@gWw…I3(cz]ɥlbO,9}#Ħ)DǢH4&d-sW}PZaXOszƫ>(tB H.JԱC6`ɏtؼk[xE~P:GoA9$H PBQQ:k;O~f`o#A;LJ+Dn2TC:|Xۃ"AX?mM[A !v?L7w jߩ.NGH|Yr0zZ#" R(4酢m9hq/ {[.?9^u^%Y"Ɉa5S"6zNABg8OvO@V=kxIgP?&z\<倜ks󇙪 } q@+1$G{vc&ҫ!¤Љ]WA4^a}8lLV >}Ɇh;~=I#:`+F!&ZҗeJG$ȗ]ӞsV)e*hT@ߚrhzp2brէgoQ]'PsuϹ~24Dvk"zG2`WOZ/LDU(ʽv2/ܭ~E@stwyO7.e7,^PS06ySNY MlD2(W\7}&lͽ djNiM͹lJ %׷8]f#ƨ=s$z :EOSe'\!j!T͹d\&v [8_j%&5SQ%D4*Řh!"/}oq6 7ZRHw88yWx\1rIdoc NIZ5,/08)ҰWXcjRup;  ~gNF$ <9@0n&ΫqmB9,!cj!MބO vGc2L QƥXAdB&]_³EUR#h>ëBz>/D'BVrGdY_E@./ٶӤw"ltmNURg_ӝI-zPΏ%JX |#PL70霋l 9qee{Mȩzev"D!SXPHå}W6ylp*TlUpVɝ`^Y<\6&'"?1ތP7 bnYƮ1zO+qCbrD1eGv2x}E-~/tk&9|r=##vw<6̿8&wX3z հpYU776giö6#j̕!m]E؁xˑ\q+-A> jF-` "[OVzQXBԕXdGR Dqqu!vR>3cT5 z#wwkj?-6ѷ3,:YPTKPeb*NwH8ril=\ IRr؇];^]ocY,v5ak@&hX>L^# 7kca) N)iZսJU`ۑ eԬ#u'(k.WD8<㎗:eloH`ʝ96`w6c`rc~^oAΥ&i9{]' wW 6/2ʇ~+lXQ?(bHq`SD3y_u"?4΄9>Z/=apVK g/""7=-GV;C6-B#XUnkGBNIKTf'mU}qcSX*-C &C2"?'Zp bG!UiCtb"Z=i1Yd}tJlU6"![2*nF_} 2&3bwTTLn3%sOCBv/-=Yn'Ca@TdU!Wr@;I7Z\ʽ:]9gS}EDm%S:۪vQ.3S=pKf&] OKf)=hN<' 9.ՖE4vm$$PT=`-ls [걊Q:S$[#?Ix0i\tNEL[ x+t:*S]-dP-Cac8GkHs'k<ZG.^Q.E1'"O'/ *TzWa #b+؛Ӛ\c!L"~c7-crmofoEQ"' gA!c 4Ixp)vyzZw󶲩$ ey:k#~"%x~6iTD<\c,2V;kuB>S@ˤwU.f *sQBFy6Q1.Ec+!W|7 v,?iNh5pQ>$%7<\|G#v?~iQ Ǝ;3% T:̩ˢhzO<@~S t!~j*Ks(8ޓfҔ0@PDYI Mqc_^ϋ&Gk4h(Fmq׳ą̇?hoJ9b;hPqf/pgo:8T2'B{H6IrPI۔|4M)' )#G}Rf⚀ n6 8 !8hNUugɽM\ -vʬ܃ҪkbEĹHvrv]{4XцvAmHeEƄO>a4y?wNs6ebEHss/<  ^C5{1hw8rY0ഃ6YJ"+-2Sx! [(^9 ~\TŞ[xZ.MzVq CVI,2] ,50nlAy^0Jm@Qns⣟dk-.1A+Stk]F u S([j{@;J;dGfsGs xoo{X[%f+h[ !l~|ci '7([!EοVZY!Xgkip6b=o3@C p5A:?IvE];SsJbznMwCZ#+4r0?g_` $ Qj(፩.d#0E E|ї\L!ߖ͢|y~ǟ3WL9皒xUa0U]' m( gƋPn(9q_Ԓk!ʳ}H56GԶ֏AqАBa*Y.Uٍ iز!"G7뻊1Ui 7yCQv=[jYzY/өfa{?_yֆǷygɰ7Yh/cj[|,w +Ұ-q40֪۫&Ry_\,cQi BV>8gt@Izum"=Dm?`]+ `)y 4 :!LH($,TELuL0:Cҽ5&wnP qkRcU^Mz㑇Nϰt1ݒ6p_ѡ|>+A.Ci90- u35+{iodrOQ1ꢊFQԌm+'5胞H/S_8)!pnOng3Z6ȳt8O\nH&)Z=jj{oYS3.|:E\n^8 ˊKmHի#ȤWRWv_ {ђ`h7gȯc64CiM}ᕙʾ>=lQG(!޾͸l{,XiS[i#*sud Ʀ@.7Ƙi>8zg^rY&_zKMDs `QqIb"iIU"P/ 1xs07_zR/pCqe] T*3,NUǔ*,P%t6 Q3uR:2C2a;8D fxVU+ߤ^p_+a2 nQ`e`N10lJV{ Ϩlц[{XY SծlVp<3'>A\Y5krܿQͥ&9 4TH-#Cs5~mV۹e_5 _-MxI ayត:qb :&aDMl.N@2jte LTJWE]_(DCGl.5$%A=JCvc= ZX^C> Wuɿla2oBV"{`mv1o8*U1(//NU(!qe`[wpWe*uFt}T) YCܡ۳cު%B{ ,@Co#s*(hͭt!W+1 8)/ A瑍B6Ð5cPH*m']_CX%zQ5㳭D7X!7CId[#2bg;ђ;ֶ[c!b|yְO )@4KQJT\`| wFb#J fU D\Q/G±,YluI"ijd)J|b^}w5u{ +T>]R݃9rOT=,f9^ңȰE0KD>.?ec&; McD%[o1Qב=X$+Kv$ΖܨѡoiB$[Tx|^0{0%#͙Ă$uCJ$xd[C&uS#rwBX׮*Vza+*5Mljer$2're6sZpa^ڼs]yij ?',."|~Yg,zsڛ1?4  Wts~u)WC( 64?5:&nƿWHd+uh]OmXz+FfȂ%šaG̕w3wODw., Ѡp&f, vR'ҡZ"kY >_MY v.@:1K-aI޵6ś%R;2mB쉶COqyĨ|{ǂޙ+ PW9 E)Lw؀ #Ҹ%;u)1P מq3AGU+H" J?V58RS?^Lʥ/w hF'DKS(pmM`=8ySI*f'-M䴨v-shX(1D;?ҮM$c=zdA@R?FR)wf+ ;͗sM|J T"s1QJH R_=~7墌_cQLISkjkN5LLbeTd-gU>~Z޸ޥ} 5in^L v5ίgs: &]Urrܵ Y,c5u(DrhjPqۢٲ#7J(I} ^DYPs?/ [m"St23'L  .KBۃP\4Iv!O ~uҲrŲed#- +|v4uV:Ix7wGJ&pX7p7-o H[Ofn&zur Qh!X#Vwtײ| ңmɬEhaсg_N$4gp A]|M% BX  ةz_hw˿gvd/=sƿ B+tzS@2\[7HC@Ev ̈i5ׁLW-uo@oZt+]LvF"vpLGn6t<KPRgn bryszP3閫S gTDLUхkFw)Ym-pa\Vl^ C;ߤ4HhĺId;i7 0~x_?KZp+-|yA3ꨇjvxePR] C '__rgDa&8 G#6b:љ=,U=h*c\2װC\ ;;g#ᇄiEG@$+h4kQœè ұX(#4W!~ qABPaJtfoPȒQ@-{v<-{ 5zq6ȁ&_Bu:2f^;beRW9W2BNMhȈ>kN OB0i{ȘVAvЅs٢(⎦/LrtVӆ2{G"KG e_޼qf&|C2v x~ht6 ;sŕusAێ{wJ '+MU'(Tŗ 7q;9`qK@_4Ǽ jy^CC\Msh:H'H_8X!)q#{GusP2~'BQ2ݿ1dDz!ꚷ[TI[=|3NN=Q8&ޮ̇ۍdiqUN#WZo8͚jv 'eZ( '58QOt-iIvHh,\[5qE| .?EnZPSvFttc(Q |ֳT$9kf Z*)\,Z=E<^q&FBJTkj' 2]Ĕ>QO5nnZ|XO=!;g Fv^mhVu}SV>P?*݈DŽ&ڬL\<3HxaiL4*,yx`$G]~/+k&4M]լ69\Qh^eb%.3o({*BQ)xny~I.[u:x&U'(axL_{R1Tk% NaK䮩۝MHuP rbw< Fc汴Qj.F4"Œcd"%wJ1¼ ~-7CiqgV:.ƠLOC?;F_ ba,LwL>z$!niE&XA} /谊̩F-P>,zC([IJǝr\O#hXV^aGHz> f8}җD!K8\ىd^oUֳ0񦛶 Ar'#M3_*Wz 8hHޅH#5T|Uk=Ɍк,?}jq֟Fώgʾ`O>A1s|mvF0B/.!#J!R9 #hW~>] DY wiGtX[֢Xޠ:Ԍ0I|>s])ɜ|x/M\9x5b`h47+fmT_;"Xœs3`LqAb,P^z4=QD ˻iMA>{҆oԨ=^#)=dU'm\iL /w˕"+UBq= u|Oܻ'c=T2*[('II H]0區@0 ]~|]AJK5G08QͿ'~OR(BAtџ'`KD?owR*cqʄ=s_#t{:sQ2RypNTnBJţq8s{Yܢ"b&SP;uj54]Sʠ拓JBDa%5M珣MYe"7"[\}Yl4\^'>Uuױƚacx}5>Bۡ}*oq]um\yEЏ9fl )e(T uz\$)O@3uagv7fS؊mgEΪ^Ԇ= +4|l+9R$6cgrUsլ'-{fJ<#/!NدG]Dh86$PxLIhq;&Dh!.Mƣ3fQgլgotD܋ֶGtAN_onp8],x;"#;Fe1-L=/]׻+trj%/VVxǶp9evs4tyn:Nv>ZYED0""\(<,$ ^NsbH-~}lh2n_ Ci O?DGO}Y+3Wd榎KOSIAEa!,4Q&[}1ڊN[גQBB: t~B! Ă#Ӿ^j98dݟ/,?Y8&I\=03R7<L@8lj D[zawUm&|'{yX H PU-sk$" |BZdip̧icwtRAhB!i,Eej6|LmX:P@B{*M$9#`^;;-"BExŠTs^Jۇ,:0s8[ffBS|g &;'ޥWϋ핇}iU3)`3(Az2QX߻.x<qe0*SGˤFPtbm᥎~d-tpKd57(ʠiV,YZ )}pnuDfT^-!r`.eȁґww\+Oߘ#7YŜa[ݚAHE~42i7.5-v?S>|;:j&~kN5jwTm. opMѕǠ~a՘^'mȊ$뵧mw %5ˎ]8 kf 2-.ĵ9#9%k; ]ǚZkV}2} %p˝IeEczJ@0:>Ԕsaƥ A;߬C$$+o/tm?Φ*U%+d"Ioـa 3EpB=V QȦ0C,$̗WAVIgs,F{}H6v޽2G r<6{4LUwt8AyX5S}P(?dHvM%IwsJ ϑ$?Lxs^h;GKxq0^+Qn)A"@K6c0^ '߇#HHI`G}%Y\b?&&."LAV7=B @pbǰgfa܏}ipʞ ]]l45 yг2=*Mo>TT{Y6Md4Jל)"lP$+yK&0x2=6YpHqⲶUCӦopAqU^F5^ٷN(l+؜SA o}E?PeCm5긅$qޑ~=b+[޺BojEULGT1B*N8Ё6aR$7S_2&=^Qxτ[f0DH>;Xަ&Ó\4b1N/hBI\,{o\?ld~2M:*3)`_=K-f mѺk;.J[ &y*~e5gC C3䠅OBSo|'X8)*0FEխu@6H*SH w1\TwfМP]`wKԶx&1JƓCHf BA$2j2ϕ+8oGڽщ(S2Lb?ZJk6n,wYy"Z;ve&!U΂L"tX2 Ȕ4-.j@ V\NeC4]:T=1v(wQ9z,{(/)Ec3~ L:YWWGCB粣EtSe/S< Ѓ(elrSb4?.޼> =N^]4I0j;OgU @/Q46R2x:+DD-uPwMB,x_Z7x.Z_f@f0&8R ^)Tm :n{`r`ho& +uVm.OeQ F"yTEJ¡^n&\ N󢺈:P ':3piY1e%ig_HoРsd>4W{F fD @L^FЦ|vn@ܬ2H^!7ː4ͳz9 ᔣ 2bt;) d1!2j@}2حTy[g~?)AbGkXJf)T=bfM͇{ŘԭLcջ. &-`9D\L6N6Rޡh3N\uը,]fU^S:0d~?wx4&վkYj8/.q(4h7RGJ~;J۱SR:K\8)JV)Q0(Θ6[r8tQG20De4B M:=F+MLl)b`oPMe&.<5BqkuSͩ0ZǛ)5VۚpUgC^PɨnՊwuڣ #WroՌICaa-|?@|4 ]6*x6)8Rru[+O7'-bT@yJ>\Z(0rcȌG~ERg_e)@ȸ!.Yվ D@Q5iIz"G_r_'?}LF !8WxHvaவtĎ(OҟHBQ)T*WA]jO-[ToĶ9{FeXޠ0 ޷1N8QAu"0C_圅bް;d^'HoV'}AN;}Q *{;]k`T>ʣpqqC nК?f~_D`3w+ $גŝզN1}C9=P\(q Q8Ҕo>4 OR@ 7+= "@ȼ{-Hrr!,xFbz618&r2ͩ=no3oX~pr5|(;zAEOg^5wIU A@g`uY">zP!v/5:O9>A#^q,XΚQO69IMF[ܝwRK'?m߉7s"UEX{߱!۲5y5c.q4-b_獯HbO!́,t,i^u8=MCAm&+U#,Bi,Evќu``j/#ܻ0YvOzRV'bZ/SX*֏Z!HBk-Na{,ܴll뚆A`%PaI oI@ּ7eYObyHLZٲ199{ /%[ 5W447^ F륋<JpXn{ݕԃw|~u'CVoSuE?=o@< ){85? Gim ,-3za%'zF@?ww$.Kug8 j0FQ6>hiBMFio7."`c3=ʲ}JuԒF (MT8k&l7o}e>WWSA$│vq9'MH|IѶ<”o* X'hX C'1oCF ::AY/iϨ}^V"RJ\5ʼ`w||QdgUMxoiL*%9@iP$Thumtnuy9sPu,h<ܸ)=׷2uPvNXzMCU .e{C?\zEJlφ yb*QK6t(`v9P]ЌH,++L!訞L%ZZfz? ߳OY:%^>q] p6by2O`73FKd_o 2 9藁K>z57ToUUrf&u[_rcP!բǥeNo0F:㙜$?/sy*5וSo_g_Q2T{L!e[`fkuxPš{ug q& &DO -KoTEtr̯0r^}P-n]pձ}L{O,'2˺-965*y@uv!2~t&}+zazz {g໨oonnaN"12а|me}c3UUSbN@s6k0w>P6g =wKk(lq{x@P bQraTVbS"LXX'zSߢV#€A7Lngh G( G bÅ"RVu3g 0}ĥj譇O#GXʦ5J6la<(1CwK '`4Cr[Zӟb9OFɘ/>Me!ZMc2%yA_|'IPS}B9mZp{EVyKpLKRip 6(WBaOS r[\{j1?!ch"NHg+"n)ZŶ ;Hx0yY|E CӚDeaCB`JgIzG}$@yO@2y v*Yq < Fݫē]|/WftҰwͪ1e*!W@h51]hA|ʴtαKh]pXnHMС@YZ3I  A@B'ժdoi^>`>n:|4r.up_'|-|' ϒV 5?4?;kK"}%J9DqŽp9FYl=0Ov2j!P?qħȧ7ex<|DgQ5Mf.kmzwUTtY)"tKɣ+ngSu%RYa ڄV ך@{fC\:F"BS^1t3BnK&˝|l r H.d W%+¿\ySY2yB. $<ϔǐ5D^+("flNݥAFP[?Enj"I}kf#"iΙ`)A邫fd>ăE.:*榃!0r@% bI/lqۄE 5Lze0[hLF9. >̄݇'k81ː uĥ3u%  COwg⸺3'c5XűMD5GE324ؓ ,_{tΗ)$@76,k#)փM"-<Ĺq[Xh_VHD'1uy8ie{k'3(:]-N9ȎvK3/\(v ~{O0 D׭fۊzYg/@Еz[SN[it?N{$).NdYiQ ~m=E]%J5Ǚz>!ƙ&Yğ G,fE!T\5;dQY=2y5RhSv&m(`32weX=/Ym 7 Lwlqhɜ-̵Wʹ%Z>mr:}H:Ja}[ޯ<&\J"s={ &u,)Edw?% D `<2Rt'mV ?67 2h{?=L|HoӦLXGG]oZZg Q#9 Rjӟ3wb l2ir.f;)KM^SӌEРgkixcU}NKٌۚOϛU5S;o'o/$8bǁ[4' N8*XSa&XR-lB %zSH|WtRyi}T7|\fq)ㅛy;:L>hy _qgΛ' IJF{DYń2@=3nN7d!.Z>=1OhlUe7Y^$!R&jvUwYE;8GuiIe/6 g5bPڗ _\UIZ;xN3N14o_bZKH,H Z&GocX69ق=o>-d#3G˙@6$ӿbki+z԰ T(b'jژ[gc D!\]P@zT 4ְ5񢚁S=6l`dU]~()5/3wאLgL[UW&V lO$}s '6 N9@:J0;Y,-@|e$!|8d]X8:˜7jz/C>) Ƌ]v}90%=~:ZSM(c3R b]U 8H;? 3F>gP3\uߚ9YJ ]`l\å0R&2(X<ߋN ?B7M9]EqnQLSIm+b0P iV!FS ^5gTbIiM\w$?WkaNjv~fIm@cXicKsj_en񹕏J?ɸѰ J4VL=̩d8y`ڟX$:E}p,%*W£CIL+XHzKpnÓh].X|6 BOpM j:X;BIt"t,B> T;6U0lh?1*We`/@~xmRCʉx klk}|]J?Q|cћ}z6E[~_<laA P}^V%6e;iy>JS۪ZU(+ʟ`$zlQu?yp?[7"O7۬ ˾ѭ |a?7V+ӢZeaMu1lK8h*cpA.?d>Id*94#09- NKAK=G xU7|ڬ 9Neғ'acE=FJ{\RxC3% {{lr'Ke,*\Q* E8l>rtH { [$w~=m[*#=m-6s˖:c }v)Q))tG6SsrRKɠet&) ,*ݛvTN/]?sۘyhXG/IU|6Xb2/ 2KCuכ͢oUUЩh~(:,-2]IPao{wd$]Җ2qZf.MjՆBɐia#HhCӋ~2 H FXWvb/O{w8S/1&,tv#w[X۴lVf()=RW oٍCy̥tҒ c]]鈂)l,q^½wGѤ3(fO}-4Ul=Qw=FY*>ơͅ}Dl @ -֟3KxҜR(&svl #B)V0eA~$OQP8i6wt6.fPɃwĦ^?GqDܯFA~i vPAYiZ*l3E|X焄")#- s;ʾ;v(!d¤;'U%R|YǁWBPPakՀ&#l0w#uP%=FF.ay4|CU,]i-i0{ƹq@f<%#:)DyUd;2_'n9JabǟKT|Sg#,6KnYr9H˒ΰX;6oVhtttO}7d5U/06l.oQU֭BKW[cJ =#V TM~OCeKM"!~Hj m:51c+mp*:D~x ]5I`Nyig[Ffm^}65uFl7F>{GqvqZ7y6WIɂw$>_ýDBp_9Qհ%OH8aH"#3>ÇN;k͆lP#4]Mk nCz|8[8,R}2s_n[1PĤԻ$VL75qY7ǁ$~M(g^xf߉k  Zs󎝣yAV 5bm; ѳ6uh}NG@ V9ܛNlw6GT>?#YK4Zުġ-_OGmur|_P?O$,~X3뚸5N00f:y\JutI;Ug?N 9ԣmw9{,D 30*P)*+HIZu18W'1{S%/" R-qǿ"# ~Eٲ5M[|m!1? `Lx鴪_M74wc,Џ a)QrdTb0!=x~~o F`2^|HW;`_(5̴|2٘i(A}AÑJ a1WVNᠮi%Ue" f5䂰':,c;$srOX}sgp-zFxlQ"7S#~hez/`;UZߙ\ÚsEҌn L)U=/$E*үi:2 :k.D#5 -41+,g`t]B 5_ʘ&論\w=rUAFhU!-쳊-jK=-Z-y)I1(fPȸl=97|-'S eULg(E3Xb8X9gDxl:$:1bÊMSkHDŽI@f;X=!DNLQrii%]GTtm@3ހ¿)yeo6g=+B:<=+h \0y;k݋hMqe YpF~A79/uU&'\4ϴ"^LƮ8_LaP\)oFiPGCZL{^!L ya(t#dO_P ^w"= L^_G^rX5z4V dӻ#[331?$ r6gw(Q8P>KY.q_ލ:X[pF glH$ m " dgk*sZMG5/k cȰT+ϐCRB6,lVj{ KoBz|x`._NL}TwJ3p>jCs2MP6 6!z>ŷnΝGLh&&rֲ> c˳O9%k䳵 ;v"0Mx#ЕwW!'[2xgȜ%744CsڔZmI;a|;va&o2B,%4!p=Si]% D&5q":а4/o)Uxڀeo}23p Y0E/7 Yz FfHZ\Hdm|;YP~50{%î%y+O ΈFa ,89(eFW$>tJ"}D2}0'<N'nf[adL.nbg%ť 0H[<𰵂%7#J:pߥ]g,zpD5G<l;V.J  ZuXלHg߈Ix). OH+t ƅw9ޙb cV~- nNb :;jDqb?rLNȹrĈggf=~MS/{u _kqugDGG~D' ˟+i BM 5/=ffcwzgܷ/7:oM,A0@DcBx>fs' dGHVpo_!܅`Q༔[M&XYL~EԪKDz O9erk^3=L<Ptv6g)?M[}\SU-234ܘ 'XsDˣ0JQdWu."]WbU^c%>h]9:E1FZTh{I5zVzR_VM_ȽwJ~cߝ? )+#j1Y'0HuRIe\yƺY۩RlԷ~h(StNZƝ]TN`3%I:~o$LYƹ6B!xj6eUU~-`Y.9͓f3ϵC[( cGjX\j?dqV:\2lx4DfTS^i}JLbc6| Ъ5E-Xw۾R8t?Aִpq(-5n3hB.(vX؉[$7vQҨAb%O$$rby/>a<^ ~#G*4Ewl^OF%Ebo ~78rsdt`)By7ao"dt tEg) .Z8zhJ׸A]&;"עI myꣽH*T֖/i# Y&^nVyZʑɚ;s\Ka}~Z)ݦeO4 C2d5;PMJYcgqu[{yıH N4  qЈېz_րp3I-\s~k ^3$Uڄo>oT(9ͨpEK'upu1sFl(7Srt4sy7}geaA4"yjeQ:`bX#&בAA7Q)LPWEtc_G>&lRupdT;fYpN:zø6Δ,;Fh&/VfO„ڒP+Z]A?mp[<Αw:sOtB;aUaup! 6x\ <]s;DaӋ u[NF7h'r*.)_ػdSREM$=ߨ[jB Ǝ4t/&Ch 5D̂%Dž:=KT,ڼR -?DJyѴ>bD&vN%cKս6Gag@rt@,VRcQc8Pv+dS/y@tV#Hm݌x2H#rb7eeY$#ĐjCK;_GnuBK(#ߙ6"DzB%` v/k(Fa ےka!){on7rek+?F%6OJia̜ZAeN\ xWS@zF N%$(r*RaL #S kBK}_[OTRW+ԟoϬH]P7178B3zm;=mj8u~Pr[DjjڵL3TdR܁܋0Ar+}o΁5a0壳T}6kB2QуLCa(ǻln@W6Sa(?!c* 4;`?Z9pI6d /_[`O ] *YF*`{)fn_!Rq*-3Ǩ>ѯQW \3kV9vޑGǵl83c^Rup4nGliP:LD݇/j$oNtk@,"8f;c?!~]K\64%?+Q~ BrWM4 kц)=|lS+نUkK3i_:b:bșK+‡o+-eG0N Vn0XCՍ[hZ:ky x [Y&zݖ5 t<0:'̎X9؟BTgٲfA'YqD᭼-$wK2K) ^VyPI0O4!T@BDwpVPwK ik%'d58'Սi?Q֪>H$Ŷ;DzƤ9{тa ?=ʭA\<+5 ;0=f` ..wI}9|-ɾaZ[spuKr8adf*kC9]+]@"d*&椕.۞mn[4C:m~゗$ڽn-8ݸSXj> D.͑41'!ƚBLy¨h\*MBVb=h?g|{*R]BPy [̵b;-KR8S;/ e,N0ܮ'TR.Dhe {*0F,-iĶ5ɃKQ4 OQ" Te Nz,assKIJKA)EaBieߨ\N(5:|]1QHHUhWK56@FU&冊F// ˈA%Mt6tFE)=ÑUQ"u"}:V/%3hN*)SXx\0`pF(tnbr%ZLҠ75/݈yx?% b€R^ƫg#*Q_@[W[ͬ|{T@aH#PjES#Nb࿂IB`ڕkrY9 G:ϟu;:ġX(V @DVёXb,6k?3[fzHko~@Qඛ5?"iwPڇ@LԲOt(VB,!p"3wkBϧiR0Y";q?t`E IT˚Pّs;1 LX3(3QWy5SNg+߁HXqM]D(RKbKWHUg AkWY([ r]I1Iŏ KAL<GTa J0!t= w1(b`RFl>dm=NhZ|tA!FO,xz";4OpFflr]ZNyGxm2:ƀܘx8iY]s[b5/_LJB;/Ecgx[ÏMT)R׼@1IplaNf7TβΙ peb,*$%-! .HE?jN~Y:H*Ą\LQo ʟv,-Ox5dXҸ9@-b.a-0(ZRw=ȇb&@v 2Wm{ܝuyb/#F(*S'"*~L)9#) *,whnShȗ'Vu?`М4 -7e_:SjO1?%ڦ} Xd l:sb@Z]S㒍ݣk/%+P}wU;)cпFߌ&1*?wJnL4j&7<cX(}eM COv7 )_ nk{rNDSO̓^SΝt܁õ/ ^K*&|u:n7"H`*6:_7~4[H |۝,6(' umۉ]H2f'G#=g3>DBU3eEtc8wM%|Dm(_u[1ѝLJdVy|^!l!ϯvc*qyH)ڈ&4zw}:)$K9fNwL0őÈdZ[Β'ӡO!XUWr< ~3=`G׉^KJ9nÞKPܿF$. Л YLgÆ*h:}[<\_90u+otj)Z |3{-eަh6\H'S(qg"n[/l2Re6>+ <;4Z`C<ĜjKK!0ܞ؉!RpQZqjh!JM7Audž3KeeeH'k^]ZyvL x$n'V Ldo[JXQ֦:ϐjm.(A͟2C y"oQ`vz+,h,< $6&@vFQϖ 5;BT]r}mX|m*KrcD2 N7M*vshZ"P'$4n7jrÉ7*®9wuPq fKɟT2͑;A0F!1i > Oic$>ZQɱ{ZBSU񫗷!}mZCQ FoM#sk 3b[kʼq=pTaVГ#r8m* }]! Uf@! f5Gu^1t=Jbm37 2p|SE[CSU.jq'K{c$h˙8w*bncCڮ8hB\Lpް,WyҠ[J3`صeJ{ov`xo> ~v 3' sOH~݇l,!/oP̆Q/K6v}LH}G7ԖP:~ b~ 2fŚDͲ;;v/󔘰;:Q^\?3c2Gaj]o87r F=Y϶ E3qm\tXYg":Hc.鄻5C|(Ywq!}ݭ{g$>~[:=U7C"867OC3Ӿk|J[=ְWywKyB1V$_u@ ?J=h$i- 1X!(a8бoTbE+XP<ʼA"Ɣ3$3h7lʍUI~eZ~WH|L'lurkm4/i@A;8֞e ~rP0i{L ik!B!yec1xg9|(:$ŷj%,!9i!;Cj&O,=1dy5\߹,]Mpd'12<c]yp@tzy5@({fF! Z7FbJ'wCR3F;Ma}5?zN. uefЯk,%N'QA:|z~DfĞRnkOMŃO+DU2U^/OkId.[0LZcka, f4Q}/_gL% zWwHzub$&+8ӆ О ,qу2;[j"d&ԀSF'd_8rU}*ܷJb'_'wk#PX=y DŽ]s0 "%C(D? 20aB^@t2<#EP|*m/>kG҅Y1I8I\X/4T,ԀMg6 tB7ú gljf#ID/+Oǥ;ɣ[ג͖onjT',Gt*thr8M`ZSl}A g1E_g\3BVخ<0$ʮQ.jh@4.`Wm ۠K1睊t1]y%:b ldBʎi8aRVe c|At̅.N-Ideء䃇O!1S*q=g$ry vϰ#ޕI4 #$ +`ҨsJ|r# TPw`,uleWE5M\[4q 7,DR+L "1z_P2Ұ8%5Mfh ϐXd(OX\׮/츒Ozw{a;3[pTjNy|GZRNT( !/^:fu`}p2Libji*&Ҭ=\KfqN,,.e G6cm%eovߦ͵Q5ՙPUvsO,Dg,ډcd'Z%E̓% -YzL+3-@qv0UԀd rXV3 U%`v_3XWqalC[jF \Dx"X`gYrmcڡU?5 _0\N[Yu5bif67X23 'j_QV~A,Ru+MjpJ?0\(geM0pUsyJ<ƥnEMvW24940Mp7C(_^L]Ȧ=_mXrDCIM-PN|7Ү_'f}D{{WA3Id][f|*}XV> !Qc`mJ3z``LX uWʢKs?|3yP>Z52਩-aOCMQyg嶌X8& {2iMbevʟg)0$UgwI01>JbPs@CjKQYZ h o1% n={[,#3&t..A œ*]郠`1;S'?Q$09͐o^ WSLb-fv|m"'AYqgu$ [S9?iJܐ| anx7k}1D?jGVc7%H^YHnEqxpv(U*eh<(/܏AE"M*NoiZHAg͞ޛDgZvɝ:hBRr?`}{,Yӝ})苹rzcE8Nd)jkC2HoĪS ĈE/)";!9hK]f+vJR!eS/BJg<",ph4 y}WvR%pA̙ݻzz{P%E'z); 1c"x% YIƘL7ɯriRo+-o_7ݬ›gʉI Jt$JE?,/BO9*(R6wt;'UfqEYKF snQׄٛHbll%pdN40˕$) 1T8:\1^_u[4RQݡ\^enuVd%0w.M@Sꐥ q|jD':6#Wz ՅS`xä2g ZH#K8U0 L5D#aVwq9zlFO"q*Dd">iTۙ۬My+-(ƭ;A'IJȯHEت9qM."v);[?IG}Ү[a2eȾHi#2lH!"xb9}nMbXA IT-."= °5ш:eF2WrRC$ܣ]y=:$lq[p99J归}%t))4-0cX_=D#],E9x K2.ʈZ&Hdw B5}p9des7SzF[gv#G[}byq OY ֑L1jx"%/FZwf:LhK̴#VdH(LZ2?XG( kBݾ_)v #pQ_rzf𻷥"Euu߉1T`VLTsx4SJuh=J>h?3JMIϛd_1_N|'# "(Sx5uQLkzg%Y@Os9ϭmV %ixҚ~z4#m#KPyR~U{IPA[2G9b{־6j 2[5LbaoYi|8eTF-ϴ+(m'r=t*z,#!% ^1_>D˰,geGc{axLQ"MERav”]N_.4iL 6jT7匷H/BxLDhIJaqxVnVLg咉Ee%o4`f$꠻ :Z++3e%;G+>*,VM7N¬?t}͡up+Q(5$,vYցo(qU% u-!y\Jud'aY鸯bdT.aHQV! I#h#5g P|ޮ<8fE5zaFnݰ&c.dU.jJW ޏVY: ҕҍN Kr_Ƀ@R] v,'4;x֍2$t{u=vqU[TS\ j'LtU֌D*Q;v%uNX*diƄ@ Hw+uLiO . el#*"gW[ֱEem;x7T՞*Ju:h|khZ둼D𼓚=RtM,+*[(&X((xk0c4kD+ tO(WMgo< 8u馣#0@nψtKCHh p' 4[{π t*p/- 5Vj)&>[ @82C4@1\p]/^m=hgx4*UH?1\?dIcO-WC -R=ۨcNc { 1@x :(ׄLu0`)~"sٹS3bB`iz)$X[]!b Smq^&FӰAcN;yQcRij8_3TкBΧZ_.29X+G 1 =?|"+q.oKJ.|M >FW`vFxI.潷vBѸ ۱HqiBAթIΩ+L}rNu ,P 7ku$4p8Yzr(xSBЍfSPYaV)s,S\{۶Dn>+&$iq#kW q1f $wYV,WywMLsl Oڅ:̨n[3QE]O;8FL ~$~Qpf#:ת!qc}3\gMחFe'?E5 @2i3~Ճ;q3gyߊڼ^O_jziˬ[ gpSOP߄5DW^<-@ d#%G$#RU.cj0Xj! \BUv(J6#D{ٞ:_?/Y%Fpk≠Œ rg2G"n# .NB)b] -7CWYQk @3\'v7 EelA֪8A^y9n:}FĴjD&|hi`lh@,RyO "@CwԆMY ZҶq0F 4.Cc_N^U.g(ƏFԀlWeĶԄkVL[gp+xfЗygX ^DpgU5`^\oVO&uv H4W@Tt'tAptǷ,OΣ>36K")k}LяHcա \knDZD#chإT+ȯ L Ifn6xn&O"%+|5DLy>RNku^VP&WaM <Ynp&GeJC,j4uV'/κ}@No3r&"l%Z8X 9w=~bħZۼϥ˕SV|ZtNXY v 5I"Duɇ7+ ar?WD¦e  aO:њ/K= *Fh{sfblWmop-^}0(zSlJD5>:ZD籇 3w7C*U)HO6[vL T~| I(B=X" ao ʡo]/CG$d!Zפ"}13Ԉ#_f~d|7kNqH{Q䟪 8T@~y #H٭@|1<=ϸyV: h }ݐ pq+v\O6߁͋tu6#b ]]ː>)7\Ps#&B@P7gp!FCǎ71i$ՄroB8SMi)*tE8=[ 5_4sMJ>w=X5ȱB{Sz.,%+B]620+Zrvÿ‘eY?`?%W_WOCG[Wt "?sHv^1O4U0F>Jܖ|JpZX`c|⊦ܸ(ISkFr4u7[!W;Ă.+n!R5u \0n l6[ 8p%Ypd粞vs9dYfZrrVhAwE76@3 tu>/fӍy~ɜ& ? /N<SwkO9-k W(1Mj;1vp6$^Ee(ƊE;+1ÝQv0rmBEWNjBϼKKxBmKm!n;1a1!F _sn- x'm y  sSc_ گ ʵEVpˈo2g 6x|!D,rߘٺHN,}6e3Y<@8辎>)֣˃gTPTD6&!2cLQ# d5efDc;8d<8:.QaYDB$)iZ>8$-&Ŝ<9ċ&J`V'5XtSIq1,YJ,,j6Y!_^4w0FGh.1-wځDf7≍)u: Kօ yx UUE*~SrpNaYxTs=P"'/hs"+@(chb x׵WPo1o8P++ Mq\{Ʊ k$6d=mraũķWN!!NaTr-)W*wu%֕KD15kqB2)̓g=q0lXmg30Fdrk_M[>@JT:Dp c :ץc[mvEo!|m@*d{S#\GoɆs݋|U su!Үq쥎F"?d)׭g/2=H3B NDfд󡎪pYIsNi:9pI&Zٽ y<Lm"{zmf1ϰCl]u-FH'ۮUA3b-14n#4Htw$ʾd3O{+ru0 Ϥ(>hLd<DŽ砫^XHNby.@qPZ%:$(i{.UXP)..J/@`| Zya6SᕈW*+[?f8D M]XE bÐmi>8ёo?` [ O/1~?ϱ8kaa6_êwKT԰]3ES!u i) FTy -v!9Qǂt9t$W"7Bm\mWNHx8B"䓮 [IRp45umYd坡C4r?76f_Kt'@H}Y AĎU*iKUU h3d6,w{* 1d}tP{O ͈n0|{;e%( xρh >s9g{%V1&<[A4_%UsD!B~zVR~oSɶ/Zl %ZC,*//斳l ѳDԑ">"T,tH/IIGHH!p4Ol8tqh-qhG#=;hc ~g6naM~o4*< @Y.a(N4eyjf=Ȫ'nbw/prsٕ{ nǜWԫ (pN[EL]d&Q竟 |@~.TYC2BT@Dͺ$_E:b_M9EA.l/uYP yj-׈ @YJ*|$ %T^k$ě9?WA/9$[2./{S,=_-LЭ= CPV릘 (v3^L׃61 *ja@~ 8;DŽTK63-B9mõ]0ɵ6* u7JDEi+BOebtSZ]oS4=Rbhc%ղ 06.\BE5ne+T$ )Dorֺ[wd'q~S&-ºztfx MtGtFMLo>d IqwMb| ESPh?Erey1g8׌*vfzM\Ijj(z$G83HoSq)_k7r,k5#=AH=ћ'K{FGmdʚR_QryNߝ8~#6,L-ȼO$ -Ni{{D;3-;xm{jbY{ဈ(_ɐD5.N=Bg^`uNTR MGS R, JYbN|`> Ĝm[.&:GC\Q qpIoqzES\Zͅ7N3IЫw "2D6 5Z=B`08-(_m7x @"8RjhG n/ĶrA #O& _w))tgF"#'>hPRމ"h v[_ԲϏ\/^ۢ*EO١ʕ ;XTAq"*/H"=[YfŐ|/fEFqiv[ۋqdw!/_&|)A44y9GOoܞ|7P˕oU,p5C~nޢWh/ =Z,&/Kag؜}4L6i46( SU^}qog9՜Je>dute\}U^5: YL)&s,f*7wyyS޲PK`~tOB@41VƸ-JrOY-@xpfZX,Y/D7P!8b0\WNimtYn2DpT$~"_9kH޽Po}1۩@mT!b $1RDR-sƀgٚ{K,ycQ)* p5h6AX %^,{[w 8Ӄ@s< *aVn \y( En9nL`| ~suJ(f |}H({3)[O[Au7; 3]& ѐT+a]*pBWXZ8r˛pVTG?`5#Ψ ?ΣT(.Ua|`bH !ѫ<ȓ/Eo]wۗXp÷|4 ,kcKJK4KMdBB~Lwo0EO+7H][0/< L,t3G^."uC\zݢO}?) x?lfB&7:F. .'*{m=1;}n1<'Jve%`$93Y X?҃4Q׭@ T!t:nL =2DayAt8v>_S2fiGxaH\9lj@T*=^H$!/p8WC߹j\0l$'N:\\8'Mi^ըqds¨ZgX$| FKmiaqe=4AZX̫t?iYטn@H\Y'ӛCƂ`2^4 pucQcPݫ"B#@MNq*U}]~M`WˠuˏV<e^\;Qg=N(xFٟUH<# ѝ+4Ɂ>"N"ಊLD0Վ \Ya4oR֕:p ȄO*[}aW\'Sp30%`!RsQ!4V,w ӵ4+q߿\Plt*UC^yF&-9 z[CRc9G>{=nBK3Jù] Kߐ9/ay њ >q6[ -I0:g d}5¶WD}[md4cx1A8|-(ː`lB3uv&)񫙘-LD"+.|bGk:A +&ͦ}5ԜoG6UVHk(L_QrxW잃)Jy Ɉb YUI+(>0%O8neWs(B=Vo n0V/pZGmuJY{3p:VomSYsTor`yhPSTI &?,Zx  Bih]φ4V}wq'# R:Aqϗ?Ef; 5GvO P*>_cE8qň'ҘgN٭䏚0/4lK9jg.EFYj(fF9hvA=rRIR!LX',;/^rUYd3f$ T? ?z2Vw4Um3t¬,3HgA:) t+ذ$ w֐y'I\:#boُ%ڼךjܴbYMmM6-or*h+Ί&ۧ0 rm VǗϩ :>{)xJ:Fosw${Nz_Ra9SM/ cchʇ5~(X(p}Z,Ѽ(Q.)g &:G~c 9-͙QڅH\X븈R숙AvuK+Nl*5p!QQL {]+E-:}EHMah큮)E1KYYxԓƫS2xWi=Hu-$bìD!d+LMނEP$@sGީ:&J1?]KX9tÉKִUFwTQA50X'vѥ`}R_ޤy)*['#xEV^p%N@qmd[9 A,X&9 ԨH >%ŎN#9ccc[3^Xš/->$7'v^ca"lNd>OCfSewXuL?W&%u^޽ 6e$bՇ~2 }c.|t>\ًCuA!b u-b7 Wyc%![= ᐱA)l |7}tY]P{݇ #?4982JvqD%-H E: o 9;uPQX_L+zps^J@P?KoCA7VFK8.L:v@,+"P prQA1[~Pa8QMeOqfɎ*MB,n,%=F/ă\;O_v‘v҆CxO̙0~u|3Hk+/Q |[%d"? P"Mx@?j94@fr]'W-Ibe,u//ns`M)'`aZ+d?*OY X"iQn,YNՄAddႍ-f-#G"˪c'6Qvi݅CaV,{LNWRS[n/)dXqͼl>cJ?'(2tQ\-wm1[Pb"$*),]\$>,jV_*ˑ˪_BkVC̤"SkA4[Ά˕ ]ՠ$]Ƙ|V-̲ [ڼ[ OV~iB{KP椴'g`wr7m‡4!EۥPfa49he%BL$#jpޯXԭWf E}b[ڴZ(pE%w+ʡ@єIܭGl✠WW *K>P~-;]8/6 > kGdg%VȐ1H>? K4# _:رϭϱ#Z+(#.c8tg ~TIh@=>8NSH+1#]<|nQ.5|:۽Slg{xћM E)DPM eEF-gLoIqhн]$x)bӺzw%wu]jJ[D{ Z7msHk[|^1aju+SףZS?;rY:%õa̦o,XWmZufKNa4Lv!4d$QŢU @KnE=9ʉBDb>A<\Юk6䰣V:=Clϝ̒e֮;>f"(uqtSO\N 3ڎZp{# rup*mc+}jdդ,gaCpK-=+G]4"Mԃ drAA8**>wЎpraDBT|tvZ8+͈_a8Ƨ,_F:( @ӧ(W4D]$]Px&Y$[sn$!BIJO֒$,Iٔ!v:7iI?;{q 3PKAJ jDzs{O;jI1u@(ԺDv Z>NBOd>_݂:|R9PrU|N|Z..v].MIJ vzc! ȭO@|5Z\/ދ^lЙT[?.`{L}=NJD OlqSI<ҟ&G-jfUx+bG9LRD84U+_lYieR;!Q @%;Hbhby> \ZokR!=mMZgpu} ),̞HZ&r8W-1 횯4)L ^f,j;_O_,C%8;"~K:LxѱT6{#^Ÿ,Y|2i`̿Yxb%%ΞXyMA-(vUzXw56=(FN/3< @Ȳ.##RxDFeJ-%yT-Tna|V4jBFGa宓M4dQ4N]fְA5Ys`wT|g ïþd(1v% YɚT2”eiNns( oqs=T֋y ZT}Xڄ?h,BD%/@uiP>% Lo#UԦZ Q܎K0ySO0j0;BG ilBIo'zfB-|N{5NMRj.M[ Ys/4kc m&S` tKH $LAVCQ97#O 1KN_!@Zv]"~hq (b]^CxWAt kW)Jfˆ*{0n]`<2oY@N3(LDD+曻µUN9Yuxyhs;ڷ}Kb!'v\*,٥_8V4NYk>L%q\o%Wb0y94)Uu1˥Z$Bzѐt`fw0m8lN^ƅ ںѲlع)I+AE /_=g9yFل~HJ=)jx\jp%k8K>Y6 `Rl ( %W~bO8uQЯCn@ĂcO+AF/{}+Qαsq=2kbc kPV*Ak\ԁ Y2I<-pTֳ?/0,QsTL{:-ކE/O~9r5^ߊL/?КtMhW's |Wh߾F JhZeׄ#8Ik0"O`R`.H,N6}؃ULhǕVm`,Up8`ZyAWQ* ~S[FMܛzEVpI8CGqaDkc| aIs`dG# %ILȳe(L"pT(Wy}_Cޞi-Wf(_@ǯ &rI-xh^_y;0CrvςcoAf#o+MS wjR8 *C <(],:bMon+!WCIHGAzW''pp=.\oDYFL|uLkY[n(2`J0ԉ!BޑD}T|Eoi#C{2y+4}yFL }PV|T 5-5Жw9/F qMhGge533~#f9Ǥ%}$)0 =xD;E8@*Zpl¦z+]Tf)δ_$9Tzm=?"M;R["%u͖.†?^ԩ.@%^#Sci/;ςt}TƂ'Pv EX~O3B/V"+cёHgJV+ol:vN a'r /f'&j?fz9{W/i/ Uz<i5ebꄁiR).mFs])Qh#.Jqd/;؟pdDa3a #F D5b(*Lk#bU*i_oTv7}x S2a|p#be>''v\lC= N 2O%?MX?h1ԡx լ:*-9GDfo>C ϨdD-6v=&OuTl`"|6dfeG'f_XԞ/G4Yͺ93v{oZ0LZ%=} FcWEWؠ8[e;y _Y7>.~`.˷:6ܦ].EcF>&A@) ĘKu_[4X!|$mXs9;gml `[f8.<- gy) 'UnUTgwX<9&* QGhj!%?o6D$}W u4q.܎fW;A:B2<ϟGeBI6WN!xh Igz֎S/+δ4@tj 6Zv3Y=vdlk%b{~&r;,]GD ]~R R|s38{H>tKF9iX*kg0g>z% 62EP%gӽ\:y 6\}OO V@T7M1^`S3]jC=G*UcD'<\̜t0<>b ^7-HN1il[W,:;q:$varޔb㲔SfΤ*ѴHI75gznu=W{@.LA -+oT44<עU:C6I_wLرX123^%32%9&ȃ^2Ww_CѧtSOy_=6RWqH?1' ?1ژZ&:bYX*6xw ('E݊}Mj^o(/@䂛1N@MMrS JV]W+ƾ[Ž:\b^Dv9ۙ(#]bJ5mkXAIsRvdzEMhHQ@.4b_>Ӏ"@M=1w~ "qX^'eNkk<CpB>$ ўd}zG=nMʱU _Rn g,GJB4"ie<>p#[Pc.u5!4ac\D6Q'c硓}vֈ$pʈ, :w#:qAo<5\Jm su6D[FךNdУJ4YOa߲f1/'8go^QqYׂa*2Y4!,j*sՎ4.K;UhR=_xvy0eC1%0TbD6zE#)41W2Fn{]i# r>ORhPH_ #\?Fo[ GX.#Kx0c:;+ObT*^Cƒ6#I?C\4<\@:]&6;R :8Hc"5Kf=?&nv&Ldii 0JGas=0'nۅԿCpK€b3l.k@WsO8RL품D6wC1Ej֪ C&3 ȦUdmYpxhȭ$(l kh֜j360-:uy,>ƚ˾5 B7H>.N%(gZz#m8#J *g&vpwDSI.ep:r$Q N.Lbc\: yKXa'G$J#MJQ揥dԐi@"oQe)8m.=Pgԩ|x2 dk&8D}Hp \qQ"O.aZEP~+{J0Cj/N@\[rص+ B,4D3 Iv~ *+_ɹII#@vxyF2;T2 ҃ŴxIIV#jE2=ӻω'"^n4`xnR~ Գ;+Ɩ]xWe-cTxϱF}?r{$d\:O%yŒФ2rp:=El&ʪD` Bwn~c2=h&P\3C52D|]Nb e<OR?ͥ2R(7A/y$45viv_;͟i r⭽JtKQkv4z*o,\`Jd$CYnzqLH&R 7P5j|Vwdw6A;Y&=j[r|.C#bs&q{4LUF`XGO/[$1%^dwb č9$͏:@=' Cߣo~bU7݃I*E&ēl|'/|ٕ70>"JU U}YDHu5}ԋ7X=?_Km ߤ/E>N!V%n%!\C2Lh5 #nqĭ;Gã K +W+!]^9-}!IqX?_Ā1l՝,,@5&vOjq5S{NhPi6?;_ pB44*"p]Dc/'6uSjKu%## #؃n09¤Pkjϟ>1K)Vh҄r#Idμ^7ȿ_$_d䯦! f#Z-téM3\fZ Se9p j^)zx٣z=;<%9`6 MT>xZhӳ% a֦%.%.Qr hoĬBHr 6\fȟ!Ïz:$5FL>PO )&?=7'\]aFqH uheq!MMxS 3Gi=Dzd hNu@AEEo_užPLIsnR:1~F\惷R7YMrzVj>$0{ hLe,4.NG,rCGI,"+ NYWyuzz Szg }0BdX71h#vl m`~ fKZ B~N6ꋩk` 2{WBF{àh${qzEp~M!. Q'nwD$°  P޼ S7S$ #b'Z޸/QeY{_!"oyR6(4E /K_Jp7vK >g ZFJW_[בlp-dRc(&'AHfe/qÅaf05J4yn9}gH"8KՀKiۍ ̲oޥkKrVjNbmDF݅n{W`T2luU'dl)5=_,I4#|~1F$mwoL^2E4b]͚FThBP(sL2ٜ|.!"6Z(ظRʽKTb  dTM} L.C-5#7-dJқZFcاF>D|QG&[mߒLQ:wz eQTs*_mG&*X'hpNsGy?UƖljNFXD1K~&Su A@S2&hV>*tٸC5j+^'3f;lxMGGH~(ŋGv:GRh^lGeCFgǿ5 id]fjJM@gvTf/(K5%pz WB:\N?³UaM>g}wϕne2zt(Jl"gC=tf=~CA~"ۚ2̻-k$UgW; ;\u(f fZ W|Ez0 SX"SVDTW#K+G-]ݱLr{tO%%e|VN1arb-I~K['MzTJɤ!Kk.߿,31|+?bs®zvBo5C6yz/mش\Wӄ%Xn\)읩>W IBWczkҥU-JB:JUyLSu;6y.gCL_h\eV|yK4}hy-;ݸSy.ʜhqPa!ɰfw(ud@#M4ğp8!H^oWȇe;Y`gq&daul̕(yfqC< >'{֘at&a%iS񻐴{"`'|$-f%Lm}mvڢb-i8r ;%GFv*gi}5<$x6FC#'\-Ƃ)Lx[* U1"1n#iH]7w4ȎB&B890{P(\¯ R@hkaN0*,z+=UvO<*x?,Xda$2 8e% ">C\r=q<+΃Oc?^lp`[c#rJFa=NsVch]b[6f re x[C2exswC_2auMH Y /7ݣ@[Mhiirl7Xnq3Q _Df&E-5^; O\eӅpwʖaDK>9'mv[ؓ/,CKXQD -X1ҕ6dOv#`!d3^iv"Y燷qSj0zvQƕ"׮hg⏪jqǖ8mNu^T Lv4-5P 5t:-hU+FǛ|RQ'/= >4FG0t9RiamϐELJ48p0|S+u:RIl#sK8G̳JmMꏩEJ]9|!bl@eลяsP{[zÎikQO)נkTMG݂c#~H+P ȯPHhf!_pBa~!eI8 8 DD{!T/jEcDq,(³ճ1 O2L42S HE|>v=7Gb]^:m3 A'cP4bn\J:9j ݹ X5#K$o7wld.ku*Pkgl̦c I֭5<5,MЕ#ϫar-;x3C#m6bf=mZ^)U99>Lp= 69,t3/0=mvz;b21|?I_ 8H&B43KOov!Z2@B&U)ۧȁ47]"XR"GO;6yO@NR q[Exgz M)u;{,ɍr$w[tZ#τ_3b :ht xAc(\YX_+LItǔZ"g!9U˖G//6EƋwwŜCcS7@Wv׸oq=7߂W>rp,<3Os]X #h֌i4mw|QƟʔA%Ѕ՘b}oAĝ~N=IP1huw"$qWd6e@PaV'.eo햾Q#'k8PB?f}H~Ņ(mX{;"i7ùC0&mv*=1 :R 9ŜXlAJ0(ͭ4ŖZ!x b0DK:Vh vE5)L!a49p>nXR^G[thFH%+ZJ-2${Zm"R.GS kճ`iU =Γ2~f~WhhG։ov. FxTJ{r`Zum#\d2PX+DqǷ1_FR!M% ZJ$L4lRHqlkj~>3H=by6r[N=ˬ[A$}"c1mfੳTnC!(HYS\ש!6>0SV)|Gey N= /2Yl03ħ뾆JR-Lz?d.Hmkeln95 T>哺]OAѠ`4×`Y]# |đ'#3s1ػv uʪ U>E ζD}cYܱ?S1==!η} WထP`a$; oh,U3IYpL=6?Ս@ j${T*HO @$t yWހkm{>.vw;aq@Cg5(BRM7(K  صd ph#rteMΠHgx6%LDKvL!qbqҢ<ss\8߃sEں>L&e]En|Ӳ7sn BRT9.N}I)-ܢ+4ČηR+ U?]`bYRo[cYvM7j)>Y_ U1O1+˂WCB8]<Ô۬|. ξ5YGѵ%uɱw[lg)Hg"-msgd BX@~>S==ʒ+Ow;LASwMF.A@Oa[1Fh>)_h,m;8FGɭpȄbc|P<]3/|4=d|V>;G&ubV,Gx/ztc:*M .go#_(QnGSQgꏉTeN?rYc@; `'FU;fǔviɊ^SwsO hb;(z10@z2y^;g=~3d P~k7Z7U/Cbn\ k@j:AjZ4*Ƨqo#*R5`87x=@Ѧcl,].-+{][yYXabq 7hL$titLaIK}vp om8d8q;#9_z34< $-L:"6*{yIΓaHQb2TݼwP>E8M\H1ڢd S]^ELG"\9WBkСQ26jN_V2)Mi\( TH$_h`q _}5(fr4`N.6/T0]Z7Hm:AέМBr{ 1%{gQV:n,X$H>ӖY{'0 = B"{HCYOD/ WZ_̀򣘱a(妿}QlT<~XQKݾpvf[O[۲̹Eb fLL5DsM'0v+"dfl?2s"XD!s> 4X|di#dUbS-oKXfCx 3vHOD^trJګh x8{HT}H|jڬo3MUekw`ft7Qze85k-Ar4cVA{+)cȲwv=qAՁȟ-Kbd*.RuygB=?9rSj:9|rc~rzC`*aOZܔ->'n]Yͦs.cxd]9jKz%O+S956HZzyYIR8d!V HY|`j ,-lJ) .|5c;l}? y3#`L hܾ{1) ^ ;_!^f|Q=,nB辪w'i8[D\+ť-aOXhgm#8*.jp|c^ - 1 DxmՍ9A5l[T^__9JȀ`yߐOGUPwky='kF|T*u\y͖ٶIk"/1"hnYyl ۻ7.xiJC 8|:oI\:̖ Ƒ2S١].l*{d[ZWY_~xxko#{vyhxqDKzYE#@z+8AuW]{'*=*5<:ϳ5~M?Q~l:L$zhX΢57J@w3-0Ys`C Ů@c_T1|ePZBK[Ҟ:8Qt/0T-Os랠V<XhR|%lE/ęT.S!9<ނ<*ni #m#JP=uC9uٕd|?J5EâEYs;/|$a+ ZGPj49^maKq6AӋCO] !AWV5R}'cla9E0u)(ТXY+=FeK}㿬Nlb!/!WPħ;SC6ieСfCD B#xv*RP#c5Ig's AD.R78J=In>8 wE?EK'kiH},\aZ% 4 H"`;S\UO&4}AւƔ2!~ɻ㪖љg,#[ωN62JwlzJ2/IpB,o$ŌV6;֯{uAPx57kSnZ0A^Z瘞;Cԓ×%^S}S_=Y?\tEr`lɟ eY+ Ӳ/ wd1at>Lt@6jPo#SquoxAҷ9ZjŀQqX:I̜+%R/V;7N#Om>x~M"y(2%pdoJ|ҁ4 Uo4fY䥽ntc^E뉄 &`&zt)v{wӯdKA"B^.0\)F@qxJ F!9Vԩg'Y\\*VgG/qDZϚAn@"1;nРoP<.jfO5z-9^|rkL d>n'Psjb: "!${7Ł- t13C:΍ s )!mғS_Fb:Ŏ7[g{R]9iy^hwN͝-J^x[5y\rjC;k,z3#N>gZ%h\Z1ZyPyȘT軮kD4m"D uB'6sT-@wY͸$}s0] kBY j3-2]6 !p8}uo߷ \L,}_1JtB,Em}KIXJ#A~+֙.d-dcٚ,rr O,5X?]0x 503}-}csfavc-W!;XbTs}ynl>;7_oO)qB3lwg{Na_aT PiZh[QQUV1"֞pO Y_/.FbWSelȁ5?{HRJ)o K>ָܤnL5a~^ҥN-%lܳn#8Y?r>ZC*g(vOmݟr>:ޤI ho0C?"`9NthComp)}^u6Gm N!91k0zC`MLEFͿނf\;pΓFZJܳWwl⸞'ӥ}#_ƛz&|%TGFEr9Fsc-SvY#|oFaJ!;{S^uT#lyPHb&1Tפyq ]@W $tK") ժNX)yVe8--A~c`#eu^d( )aRkSc g{d\0lngi"s5`D9RoeN'n,}7{ oMh#&hR $EJx %^KPCxtV;˺-zaXyn H9 @BA/WB~tT>|O4 9ڧ"lV"= %9 =nϳG mR.{N^sY:@idYI޳r]3Ɏ{>|짽uX/Nɿ_L zhTRLj^}<<kم+Zh֗_o٬ qj$ !\$z`rmA)%LN$}Ԩm?axbLwRŀ[|੅բ6ct>MBͅ%y8\#ǥCiKdK|o6 >3wN:.!POI|#mr5ֿos-E1/կe0 z;xWqIߍxTAph]1krD & dw ra ۈʀlnZsK58}Fez[$ [Vzް iI~SC@BBY j/F~nDEC }3AWMX4>[}Lq;A}4~c=ͨ) LL2Дd2OM;j[3]q@2ݛ=R, 60\ L(MCnAH+ƷjK|+مdиWG2ۢTCϹg_HFۚM05t,N&?+zGY\|h]_OJt!*^El0"^.Oḩݒ׌m>o6F9$lk9YO8A z)X17J FPD.vw+5Bۢl< T=g[uh9ҭZ pI(M@{++|̶aV xD󭽢l-kdtaL~­zh,0ŧ5ܐaEy'Bʨ)R"yi9?x?/Z/Gnpwl ;̜LL?GJx#-H/c˖Vz/{:T E"c $L7n2ͣ)1k߇(bNO#X| D V4rpQӓϽe-b We3(mKgLT ~0Ӣ, ܨWHZ8WC:i~ƺ 9ݡhE'3VՉ48@lwH-9!j9Ws啱tCumu)iBlKr%_E?mE#.|pw"w,r2"ΏM'KV=^ɧzW_~&-2qn5J6ZdLR?NCϬam!?/AZVM.TyI1Sk>4yy1xr}; ~T=kofإ }Gy- Ѷuc}Zd uhL_M⇩sdzH8 )%`v) OΒ΃r +], Lة|4@,-iq.YG0S#;jvnTz(L{ r 8օ4Z 0]36۝-&MxEgAbs'}a:ipy0bǴ3"d-](sb-12/6l 7YmILkc+Ӌ[UܴGpՐ(ԕB":c6p*W 4TqdD-*~ж~:LI@i'Y L+A9%],\jt߼[p[fZNTi>+=̓=rr@ߎl Oh" YI3á \DVMt;r-o{u;76֯^0E!K$'wNouh&}~*4f[UN3BȦHϴg]Z ӚKmkrn^ń`ڪa2fj ycŒBXk݁: =nyMNɴglNXc0>6_[9~Z<j[ttjO *fս8||K1bsL4kDYrhq1B\MrkJ0XP̢3w,$2/fXzԾ+8."b+aKz4%.V۔!= 8ϼI'O;>: M zzu$%p zDҊr }8H//eeV{1B\S! K$'T f~@A 9UUK0?w3[;E*B$4FO3' _).\=m ҫ[콣jO{S<Ψ>ؿgb0vro Guñ't` N8ݮo&Yr34bHbR5kJqrfޅM5E|U|M i_=DtA1&K`0y.{ =xyd?Ymр<ߗLa0SdI%bH ύ4C.>MtU{)W>; {њP 6Y6Bo K~?ҡ>N@ÊXn g \\ye`/@_^jrvA]Sx\~K^|h i޾bCUU$C0!#l>8nqu4Hʺ7B NXX^bʨ)qJӫ -ۥG1q TZjV#*GI>IlǢf2!6"vm?Q4qGq jCynɩ$~ݴd'HbMὃ OGDKT7 (om О@%Q8m5v,*$KVR~#1RH.3W;NJтfg83ǵ٭JF-4;siqj#i1zqRЄN9 ]`p`.2wb+epj.B{<д%LO|%l fUV3+Q`YkQV/*(c;3ixIҫl:x(aO*)KOm_I@#䭇c0=>ȍ*zjUILotT 58 \#I;.!g~epg_ζ`^{6 SJɆR9$"6jBS k4FSV^m+v DQ7pqϺB_i&(ZE dAnh&c&ނNv tfxhG&^.fcuk [#5KEAB y,xj!K= KI,-1]o6=ڤ LW~Fِ,^.haqd"*Da!f[ +Jj1l/a~5/Zs8ASb+X^&Lb&.MsifSvZB .MB2bE#ՔG>0 eGM?݃5Cbd\ù!*ԝ9TxE% 8IPu0I­^BC%U"Ra^T%;X\N8IGL y@} &GRg5دg-o"D2 j']{`A0SW^gp&|#MV#zw])qN/$ ]}tx~,7]Ά6cDCEjtь9jv.E\:]buӦ\RX(\q-%E BaM(rt9q 3-);3"aQ}[뿙h})UVU / ${YSlIO^z+Ȼg~9pPU YN'.ob,-nD'jzqMXhHЍށ5tߪDeQfFL쐶wrNִYD}NW慂9a: olWe;xaJf&L:P/gD}O !*T9Jԩ'<@`N Zʞ]Q=P)ߩad~}E#3 g~E@_ ZWx /໮ܟzzoSe[J lJػ-8o̲^OŻ 1vl=r"W-YPTTStmhhRàLޕ<aj{Hk,ڶ&}5SZdZ H]qF#!ξ1**v_(s\ !>)F5R-M5'̽&e 3R5A_YPk -QݝO .'{Uw!IBE Uw{A _%؍8욀2 !#!~~e,ӣѯ0ɰW6szVOŴqQ'|WڼnA@#+4DrS=7@L(!(=/2M3["4*c´χ$汰"m,Xyћɻ~% \=<.'{]c] $UL$Iҽ ֳkbk_|ʆl;35щͣAxaɂy.PF{? }%A?,%@H_# ԲS η xI93W+8rάjJY!aWClq:q%Pfn5(/ZӃ{[+<1kxQjs(TkSߺ-'Bv^|m/^i"7 `2Z *KbmMxc“g7q/pAw2 {X.Ҳi R6$o(Ox_hH 4@,V(Up*le~5N+OUe%麟K_<]^(\˩w/=t<:_9k0:R%>ZUBpeC;AMBF΄%HR`Bhpzi9GQt/]#`X@[#ZN03l:חqy =F22M*[HN&)RFd lak7|vP9[s 9a0Q4UMJ1q[A)c)[R3By\';KL"ӱaִdZ͔ ?%f˳LW]8S=.p~mvdYNfW[Hb:-ĩ($P5GsAs_}km!j0Zf*O!#&*wk+>9&r=>k| QNG˒OF戅nK+uy #w5dZ!awg\zu2v5yFk,$Z_n߲-/=KT}=dBfI*! 8ͣVQZZ/~#PBX6[y,Ou| NR.vQݴd4 ^P rQ a|P4…K bz;B`Cwk qqe22N&P)w03PcQ[2ɮ3jW4v`@cwеdRߙ <`0*NA ޳Hrq@]ea3Fи`~OT'R2{kwB;j$65)+Jhz-􍂧Z~0mI x?t-bab3;:dx[  {kM=wf| Lgu |O"?˄T VmZzF' ,#Y{>A[8OŠޕwt{Yi%RȭA+$Y/.2#9`0)fŠ\%~m1Ky% =n`FB܃[ڴq#5]oQ?I+  |Sse)!#%е^@j1)'fHGE]Ńg?_ $4A\DQ0A G=_=q9X;|sMn 1Kg]j!!&Yh o.pE_AR*$'lɽsJMPrj-хiQZp'>hԕN" FzG+Mj\$&%u/_Uځ wv%/^|YD$Ty;SO*t@x}+Mnڭ1i]l iާmI^:A'EĝpE !`FX SNu93M}{d+0`ќqHE)[ /;e2˂B 7Bc_—x+uAC&5tGr94J fC T J\ =P2jxnLYy)8GgB;͝u'[lm/@QbjYJ>LT&XN68t7cf+Us2a?Q+6ʿ9mY}A"5FCqh 9 v%DZ^xէӾ)Vԩaq h?*̏q=,m;qh#==㨪kfg\';3DRuBz-,\v}tUnhT/#5( >5 ,dAP- }PwifRU!h0P~9bT\@լTxl*qrh!źy;I0 :ɳs3TS`F2vj.2 _ح ୎{yPْ2g ixdM`j'|EJTdtpq3qOX6@m\}pu\vR8ϴumr{Dc۳ -Fu?cלʡŭ'/^:*Α~`hwGsjЕ^P 8\,>:"QIWX}4ʠڵ*/' A&IdHF ԥa1 V*NVZ|+1>E=)=xd'uBj}a~HIGb*F]dukC?e{y u瑷b@7U`=fh#E o<0YMth+&BgE<%-) %3^?Q(ҟ2w,@zaԷ Gk&eP';M;^qsCn@q4F_5K t<'1/|*Hč\)RQd7,g9]:wϤ׬Gkjk`UiV0GEM}[(^8;OěOGy1'ÀyfLP4R ePzA} 6~x7cͱ9g;gۛeP@Z!A,h¨Ktdma!Dtv 2eg 7UM7/GNVr}^LKTcFu5Ҫ\7bD,*јn]e͓hap;pVWrsK"^)Z@5$ܔlMk" OOM5wAZjC!ʐodwsIŽ2᭩ pX6kՑ10D/nύ,OdW=}(FtDj}C,#='p[$k2}B#p2o 1paȒ# 9J7@ :!̠ =ɿ iS\F]>k7-ʡrXEOkp^~ Cùj_&m\c O4V)4EWl|!`(lcN1qU)AJg4"=*yH)"d֭cxz@qQO,n쇅:/` >z?bA u«խ}$`eBRl6nIZRJ/%( a)v7+?3DMs,Qd+&e|ֽ5jQ*s! 3)k 5G>$;qpAHY;Nfcaw.8ylzXev_*bzaEuclļ"N:G)]|3bcpfCtl x C^\OL`G^ wu-J:B8T<qk-"ƊL͢j=:LΞU#4QV?B k>8"w3h G`B%q4,)#ݳPVX4P#u&*Ms9UkgcPce03T/m6c? ]>rC.¥@ P,Aj_iѾ(WNyhteQu*}!1 lHμh|g@<7įM"mCAq+"%l;7Iܻ~1wo4?rtztMge|z[q4˴]hG8b$l'y& Ys0=%XmþGT%!GɫӽFZ&w8#CAgS=nQO?6N-l{B`!\&c8VDӚj6Yߤgg|;@i5Fy>4i`)Hy1O{E/,vQ=(Ԑ4@ޛE`UYxTW##EIFDWvQ1/d362l3UD!sδϔjzXa[ 9. h_̦;)16@G@z>:{Zc ryPK(+RHStQw\?o?p>Mo' cRgqLd~nV2}|")[ILJwo_[t:iMP6@{̕zQqJӱAFcGⰱgAh1yP"U@9j­[e2%&|j!tqa'"Mogc)aZҨ$ď?.*ȇH&z,0Dϯۊ! bol?%i8"$y(KmYުdY7&+{>ߺ,*kd[od~/uT>ӗ8FWX="w `Vw'Y =fE_>eB"p=vڸZeͤLNNLe.BsMN0uzb[<9-&eImlbQnqRR=ګ*B٩0dA%n;N5lX:mrc- M[L?V`[^O[-%j>'0C7`Tި&KkƖDzw8TE:`4z[[tgrfHh@o q,j,"`ljEHv.4{S] $[ :ʙaF:pb{֓7m!B@tJ1 OS 3kV} II:Ş,p3@Jdg.`\4cna"?DViIvB~V2_zp&Nzq!o%Q#v8lǽMٱ[ga.*f[uxC)2p',0K $AQ]ϿB|p =`n{([:'EX13|˲<:-ᄓNڞYa20]ꖬi<ڰ&ClvU?2g?v? 77r%V} XR+t8ЉtlHEZjQ]`❣b漱O !opTV.y2+AqH_3g9w(NSKS Tr4WTF)dMHԲyI:hg{e]\ь{EhakL;9 +5"_H]W "WU'`͚KɘjC>& ϟok$~2Hi^vs76TpPv[z%M灌{ N߹a||jBr *:^f|BţrXa_+uPV.Z˶Hjݷ)'~I=I!#Gfh(78+O忺 <Kes߷[-tX>]xZ~5h]vr/(=Е0uayᝐJ*H)I 0/V7\T9w@kfʹH4Uk& lp>e+$}iU+4jz\;uއi=>ԑO' 7zɠTOF#@?*-)X\`,|\;z⸫ͧc\Abu0^RlJ||鄉RۻVt+WlF\[Hf pak%(ky,  %qe_% +l< B:v [0"4f$ XLP4qCt Dpbnݷ:jy *Յm/$ehOa Va0wHlCqx@ x];_nA6@E4#ck\+ 6m2d(+c`m.+x84B FpTnkGĄ|B%H䥡k{bϽeAf#1\VT{Tl;usޫ9e f$:\pX߱f G_ap]"TqU>6#6 :Z''4,ʎ|7at2 5(}I5=c(|.U dRLCFQu\U$=&%9Nj  oF{p4l=kdx@]s/{>əPEyW @r"`QƎBÖȒew%ȹl]z48D60$-/0q/`hQ3\mg碲(9Ǖ Sý!7hw;v#rlt:J%yUߤ])J~b:e_Dsc˼[6v*eJEA{qsuH<ƾ/|q~o/zX2$#0ZgP>C¼ O`uS[ dA^fmxn W2׻nձlfAJ4=#j_6wŭ{[+I0Э{մPxggݞ Prg3蚐|atP/`L%[t+2۵펷\܋s]0'Jm #z§ခoa 9զv۩9w*$|̧/i\NJ5!Dsh'E͠>=]W!7J^x07`r!Z^*\_ܿ!.^u=\+/tH;1MJ"wv{;"PDM&3>iѷ˴zRjG} ׼@)%oҢޢލ7W=7 ꤣ?cު]zo?`ʡV8J_7XNib1saY;mV`9<#w}6lcUw(3pӹpctڳBaiuw;bE>"G6 ˕KugOAz'M^Dž\GcB hU  {ٹ>CĒmEN E?aR] ɣ~]u%YDюƓhAW^d !ye Z[r/ʤڍ\Ȼ=ZGPŃ4Ѐ^P93{`6ltm ˜BT \ֲbYsȧ$ 6ss`jz Nr7ƸE~#k4Aɿm|[ yn;4i#G襴H62y%J1{ԥd}'S3g({v2;Xe;9p\k6# #ɞV]|z,bK*%Pi J2Tȴ|ˑ✐BŤo3XO>Mh˵`%nܷhݱA2X&m odfu#FEx- n#\hg Ֆu|s\?$2xA -t=8&  &:ۈclb7Us]nM8Pf2 S#>Gsv@$lĶLH{l(1I-kw6<ChYJ (Oҋ$`zg>>Owc3;l` A81OY6a$ OEr1Wd"v!V*, L ˗aaaDKJBJOq%""5l)S ! vWf mkxA3]hpqWZ"D 嘝J)&] *3c Y<P]殺SUEsGr2%bl-(kc2MXgnɖSJ5g"w?]πJNj<{ Xa/[vJR;k91TFV,|!+hVq 9PejmyрW9&K&{H_Y;-^@JW 6tHCn i !jސX fAt!fNp6ƘdHU3>w>ieBAtoVI0HfI9pu7hm8ľ9XB7Ƿu n$/0M|G@HLq:1ihiW֊Yު몒XC<^>k&|#?nֹzsp}Z}~~ ĉ:3U `ap$Gxjc(};!KF!1mQdJ4 zA>j<4&6t@G]xvme?B>v +cD}Q\"Ɨo't`l(@+PhPPD€H)r,i*tnՖ0ё,}rY:XT̳b̀kaY_"1 iP-1`Bxx-6'^ir4HSv5cφڌdq-(*{N1ypȴƹc;c+I2Q8ImUd(S pXb!:(K̓ rƿ;ws_ Y}G6aR1@p]2n$΀UC7oMO}6A</5<*t-YYϴX(x_tgyda d'Z_.Sﮚ­~*% ^W>9>!uTF1fsG/.-T%}5+;\LzV{|j  rHR @h]l0b_aVX.kj!/xF.$(QqR)xn,xA״"_AhH]~/\XR-A:SHg($P{SO<2@nU'Qelհ@B fʋN1i?J|b> (ϥ9~?Z[U8ݸiF(I7؟zC]{KNo# fo(-yG; GPfa YacT@. nbeX),#(`zZDn;{|g>hJ@֕Z:›'dnRP |RIAJ7Z(A""Riۑnŧ]@3Eo\"TC{Ma=ZOrBWoKePXw] J6s^xQqB{W!.n0%:j0p` 7/WJiUYWsZ^ ʤ"@N}fx#&{G*+^ȇ1jɈT>MI %-e[ِtMedzrl秡3*n?컙Uw?@k\)gߜE:*+5I'|[nz dL:H/vtq_l _/NjFq;  Cy8CD޽w!R7զh;^$`p-{pi@ jYύT,ؾ,EYP 1z4Aܒ!iFl3&PS4OC+YM i[;(_AM)H㏬r#.b_6]m&gp=%+ \?`vS$EKƓ%8C-ZaP޾-MCJXN^rgEJlx k`wOjjzk][N}s Y*Dk=ڠP(C]#0w#<נ1xsSyx YQᜄkWbgGv$ DB",Yjyf.="]Yo%v uA*5Qs@Hn0{ gij / ۏ}QZ .\8쌙bř"|GyxT08i/[a6Ҟv*Isj} 7׽CtۜZX#èZy ^kAJπ8w,_'#"H r3]:R'z!p ${vJIqW>az% H]1F=l;#NƎuScbsoq7{sUqqԎٯmrx!÷6!F^j->l?ӳr3?J <DܡCSi3hEn}5^* e[)<~DRpJGdS =.mCƯۻݲVFs뒉LG6:'ÇqR MYG~}xr!:JMA@ v`03m~ޒfJeN6mpnTz/j-^ȏP79zHHa0nژ72;.+KO@ҕr%(zQqM ~tV0a'\FV*<7[6&ѝ $.VJ5r&۩ZЕ>q"T`O~2"<9'( xMTb}זv ICANie{ .&$/'rS_N% VQ$P^L]-\Joǔ)7KrYXdquTePgObF=K!7q[=Ţ楈  q=/k ˊ@&Zud7hWwS;Yti;:I/okMۧɩ:*K4j"lu[+> ?G>_ JsM.A@+–Ao& ,IDbul`fmv0-VB~^ `vv@0K|A>E<~h u'7BE['^.wm,ٵ]ޔ.ӚrQ:bc_kжŅA\ F 5x O=e>iӠ+h wP۸ ̇6B{cl1 ;2xjuseÛG%oC4L7yirдc'$̱>#(_ iH/CW6IB)Oeߥbk $P]=cHiIռ&U,^x2Q\"r0=@qx rW!C 2˥3xc`3Iϫ&76θytPT}u 1>.AN7xky7"³k*tlezy%lӶ'xF݇r No]c DDʯ8شc$l4+ zYI3&i;?ﺝ!F݁mcUIwt&Pu>09dߺ2zk bB!Z[!aY$8cD^}\C1wf<;jC<ɀnPdn\u(!8] ;Ab.d AXKhÍۂS~(ytÈgmT_0STR[z#wvf3#D5Fm*T`c6)>MZ}@0+MN){}__WlK8jR}8m_Zi weB YQA?N|>&d[̀,'Yg?9CҾf}HI'̍lKGnw/”'✂~۾y+l \ PKճA:V\/aUFۜpJ2Z*;Gp'=Dȏm{5Ǻ8e O=FU\W$TR3*kW#w3,()m&l|ڄ!|{+s'.>U9Ƌ5iNKJ%$=P}Jl}e}.?񼂫q̆\ߒ9?`)!`ߗ3g;9jW{CkqFi$1YC^SLGµ7&Aǡ̌-0/7!T0pd bl1CkCAպvˮbXyd Z~pR̊d[n&o4ȹסpei+uz?t#[e7tώ8XNU"HbCڷ1>X )q}Rʡ"&i*N$q9~̏[ecj\Kꝲc3;C+D,o~nzݮAa6j{*Pt/ȯz:s|@*K$Rhh+ %L;Ÿȫ;DrKD>Cm|/låo; Xm/VE5lz$m!_:S3of峅*ff/5ZJd9rwøLIꨤe`?zIno M;9xmߛˍn@t24T ^`~ Pn 䎛VXV^>a&.׋@=S@Vs]xY1x+M9uy؝p B/d*x866R/g䦮}9+sF8EE O#tD)ujݓlQ1:t%-%S|b`o"b1-^{rR5;@rp 1PEJؓ}V&!GC8; rExW41ڛ Eo3 ̜x+u<y~;IZNqIدFS(=:JT, ZcĘò >1:nV@r5X 쥲EE|i_6=y (K\?hqy* 3A sI6aY)-yHp(aQ1S SSV2܇']DJ")`MϒIZ~>%&쵞HrC:seţZjft>UӄcA}Z]_ܷ*i A(ޟچc 6/$ 'K1z._^4{apqtvwv!s|IEL&dCz"o#YDYSJ4gT|PuMaKz$ZmF XGؑ.3|e;3'ݿ+gqb^Y?9ܣv҅sԿfW 3Ag^pn&CѾ󥒬$I $B'tw ^EG&\O+ ˠP}F 䑩+CSZB &mtE3qhTh sԑ%שRt6_N /BK5)̛.w[g,I;C]˴y ] ;G20!_v*͗A"z0@i>-sA6vxiymm4׊zxq5ꐯד~'GNa,2N~P'Ba`!ۥtrO:(G!Q s=ʕSOKs5%]0ޔ 7 g3os}MrG#3؄rHg|W s%bp T`7cA_' ?2R v}R[s(nvpcI;~byJt_( &: 'IO1IH? I)E)!j_olrRǽSW;uY |q޾vGbn } &}EC @ǭ*svg)̀I|EdRSWrҤL6ܦV֞ovj,,Kc:B[y\{ qc zg͑'<-Ihʰohذ.KH%2gO_$ގl6XOy8u^O %i>ohc y5;# 4_m#x"C7# |ѷy=ւ/F(AmdD@RGv)}w?/(9H8Ӌ'8x-hI3PPq&0PscQe8|>Jᝊ~t,;{q׬8isS#ʠ_u8|U56pz9`*k", ћf5şzΡᐙU?輜vj[m_Ùy䣾amF/kѼ̃}24:B_(I'5A$´[d2t%@;ՠ+eޜ |1J^d]5F4ڄϏ0ΕIRJ$aiJЪ㾼qt2 el^Q ȀC2 sdȿ}{- H ٷhxpˤ5~+5[ZXp<=Ey](y37#y%B_?oԷPo7AowM?I_D' Va:5LSUi}h{4sx_}J !AGBEKNRE#v?lcz|t")2Ru\[>1Sߠ~go=rRRM H(Z15fqz=Lw2>f.Z8>˺ C4Ɂ.x|lWwij%o h]nFSo6Uμ*:QQꁴEhJ1XISC](8St)7J3,wcp@\1(Jɟ&.sȼaUD'#(\?`d;0ˀ+ƖcnjƲDB0\h[?ZнnȬjJ xLϗǵ zwq|ُg9VlZ>#/L>FE?$i7ɘxIg-XpN^M/bL[&XƗ*x8ɕ~2CA\f'i|˞u ! Hr]PsۖΉGdkRJ 1Ni:+)pv8|0wa D*#Ͼv8%+:y+f` Sa @M5䢬#[= lx7/ϲ:z(kM- .x~})ĬYB=IfLAnzy IM9X[ &uW~U5w8yJ  vIjKda|@P9uprU_zTčA8qSi;"#$I/3Y߂?~R'ώM1Վ;p^T;3]Lԝ.<-?v_kQ0Z|^h0Wz~?!&#nKh.,QaXp>P a#o= >{,0p7a&\r)>Wp)'|v8"z nUۥCߋug{!ئ2B<:^s+'+Ն</9{u\C4MDsySӰyuz*?-DP9x\lqims+Yk*D9Om;T(EADT"ODw3#Msl1x݃Z{4ЃV׭HW1А+Pe4`>da a,vRvN#F#vy[0 Asj<.0FQ4w\SaOQ;vHPTH#N&(I3V\[o1sB)^u/# P^|ApH\YpvZZTP|*XQ}0 dUg.F~E#VtwˉaR}kX [x~}|a:}l])p ћG(8i]UqQ&,ErLr+TxYXIbaOze;2>~mRdR'oKV8#. XĮW<$A*dF۷.R䱑+!\:@YBOףwi&3gאָi FֻDW+#o rC~bфD(*CZHcg=oUe3R}%,=B\+Z? zՒԳ.`4Il)*8bbn5p3q4 S`Ԡ!A=GZJdv80@cnF5Qن$#2ڄ#hPH^[1ߚd/u|L.R@9)?UzYTf@fKѶ>b+ 6f1ho2ɷ͍JKԧj䉭).MtXmK]; zAֻ_R?@MSF_٧z`H^?>'#"ԯ$.p뱑De¡f*5Wl\b=kragWaR=P 3єkh2ۮ].63SEN\k-d^yO3-§NhO> $=hc_r>z]jv~@Q3^!P 5}|lBH/k:a܅KqV:R> 8uUQ*>'2݆^b% }N!U\@D ޡSs@i,FX"fD,RA$tJ_[XRo_†IYZKJ?>x?Ÿ@Z`GED-,Ì[۔X&dU:#\ݚ9= Ởqpñ6^6daFDuҴ=J!S" M̦o< %@oA>'Jihtĸq6O p1+xߢ5f".?Ri5GaJ&|&qν2OŢc+zB;.lbN]}O9L5l5NeTz>},^ 2V1"6 rD0SSTZ:E{<,9b= 3ߓLJ,'HgcoSLV3WBrw0D DBk'^ a3PL+S~{t&z>ѿHqe\5* PV߶oSmQ TzKM4 ` wZMqSYGau>{;IJ QFqƄgv*ub覸e]d ~5&OD<4]G݋}y|i/cT֖Df1 Ywy…`3NcM— 3G/BpHF1|. zsTK)9L#ZU %ϗhN6 q=tR#+n(A\7eYϕ ) X J'~;ߕRμ-=KI_R"3nL%ԑdHEcB2>D τXѻbS]"nA=X`oFuI 9#gz`f썎8vE8]π1ec^ɲ ĩFg y ucrlEBQPP*]w?.- grgWcqP}Xb:M?w Y/cXL#mͯ\*DQ{[a+zt^Ƴr4.t*8m6vZ{ˤPW}9T0p45JG^C`K|43J8zԑ01\)O%uLũA\KH%a'wN 0Unb*> FC^KxƦ0ç0),XH602>)^kӧJ;4y<44kc@k74F-U?t5s2pzT;XqYoIК4^Ϝl+H)5=0jk5uv"Z϶]9~a!>E1GJ ox1L]*–Mq v("{9"EX,)-+O57 f-&}/3[cWVGCT ^x|ҮQa<\SKo (jaɖ%3 ̭ Wtdn@?|WHcd\I*ic8 S3Z ԋB:ͲD-7qՇt-h.^I+CA*ۯEnQGHE'B)nrKVuFa`}7S°{mcY$ ^ OF o I<&kSkOŻH9P^ {Rsth*=CV|ύhwEl?E z@+(/YtՔݠ}%~A ]|((8a̞Zx.ʔumh` ];Ћ$~xL\)>jhM xwH{j}Tmu ߆AZMLWs>Acu%|P kۂ<ը+RJaDF(qG:AF19e*\]w(\O`#-&|H> )EkH.[=L#GWԢk 1S? Q}\XBtRP>FƁG*CG^]YZAQUy$|W7.OBOb%ٯ@'|+(E߿bxa3xvkʐbglsϊgf?EGÄ0< jZRք3⠰2T.5у3QƩVpn.eOw(xV1,K}eV;E֩Vj#Wg̞P5T\+X0}Q&1 %ĭrJ$L]C۱lLϲs?aw*|! 'dxMߚQPTk_r:_ECr5ȦL_~ޘ/#Pp?Vv(SB1Uɚ&jc[?N;Hber-!fJPJbs/߁|T'=.U(v_t[8)xW5; ŠFn'D|q]8i޹Jt tc~qX-m)/e0uMt]EZm]X/G(T?kB=m4H7pLXw dW* Fr8$0m,+ 3Q|!oۯ.&Cbp/Y#0.<;ӌ4 ǘcU Xq ЫTw W! ,#!䌛N{+/(JѿVc:c< ?8H Z]l3ciW^~1׈,D9ZxdҀ oJA&ɑeuBƚ7+ՄnsDu_O~R%r.Ï N7Mz?u(joM.wc=Kv3| 9 : Pʈ_mB\)uA Ҋo:'!ymYTR,9(&,TY&ӞWZ&;ۿ"."K r5{\w"$X)H`#n9&zCe2^$R ɓ+0$x{}XVyKĻf*SHlsÂU^jCڮ(l⟻A26].<;^jc~ dkrRN~:{z67r;kPĵgTK?s~{["?S?D`RmPyU?[Di/έ'R_(o c:!7h& RuZ []_7!֑0.:Cv~1t4S8إ]={# a/j4yo9O"(ޛ4$Z+DVm_Vw9UW[Ȼ+U>*]^o6b'o/XBsKl_`t,k2NODyt0mj\<t]ƝIrFObڷ8!`^\#KAJCE5N 0Ey%ЯyjR80J؟gbԫy6VX˟H#X}Y03l¦Q˝3|#]<{ tƎZ5)Uj^%$4U/*RX8{0` "]@p'K((nh:hUiD&Eb;߬  1ϙȔX2LP]C$y. ݐ-TC*K>Y Ni7.StZÞ7698n Z1İ }UFV4h)76ʞȭRw0V,M'iO]ށH<ŠKzjE)䈎ڃ2"rTjbzPT+8+H:î %?f[]8|w̺EvٰbD XP}2{.^,A{\<yz0.I~|6⡈*u0[hxJr$ J3盤gN6RX]-x<䘚#c$S<)]3݂3 3 E⿄˦-?qQ)^KGfODYgi[ L ag7(AMrSi*&vd$%5<"ؙ?z%zH? ]2,A-`*gb,|2m#k nmnOǚ͔ܿ|hd.k+=ah3R(NJqz;rُ̛u:GC%m ]eJȓ7*M5rTWGWJkBH+.O`xN]koZ#N.`&]Jh)9&K29 F}t|Uu |A H/8_]62 ?gnH [*TODRJan G.ݮ~c^tׁW6h0Y G NͅIm [f 8fѼ&݂oLSjMKש=LζVM'@Ct@CcJ"Xʘ-?&.Ql%rL 9&cgO215A]}¦P4&t,qr?3>{3%=4*U*Y*>-lӯᗘ,W"+Cȼd?.m*|jpo&pąNԊZo+Z[]Qk>kɒEXXI_+oT|8b;6KSLPCoi[)^ ߻L*րJ~-[L[@&%l@7ƛҽ2?nJO(q|͗RÞjXH HO^X8X4&۪Rp LtFn_>s N8OH( A!@X/_, }v0=i?[A=(Ҕ*}Λ(, 16ETO3uPW(EPCÊGw lqQh\ך: ptGBy@dV.1gAsIIc^\}1'kdx p=#Ye8rCr`Xކ"Dъы!퉃IKL&p-Hee蚀 [i khI(#@\x'xIk z\aIcRD!\="bַ2Y ʏcL]+#4 h-2QaQ6xj21+Z^}K5#“g!=4ă! p;5ߠ1wi|*~| |ZcS`ISTӬt f[RT甥 i*ԷKzc) ?W;`t,a#'ۆDs/LsP{ڔӵEW` 3n'Y-޺Z2aEZ#vjnevKTi2p[ L%,B5 Tβ] k-+!;V# Z͇$-"P7 8gJ$2U-NS sЁ?݉rZj/SbaY>GlNo$vZ u㲌qJ{(`Sz< hV{}x8MD05x,P'nUD|sg2qc me )ӋEmG^]~{&b,W=۬qHKo3X4M>Wɏm΁#aJߙ.񽃍sqG6L,n$3tZQ&u;42=+*7Ydsƿl$??(;]rA Ʃ/2{ _Ƥk$lZP@94,_WE!f}/Vh<2gl ߔ)akat/0e;OAeNp-ߖ,я43i{]Rhgٲ٣b9h{t>BPzBkE}iX;@Jyh9Y(`5HkIo4gD )=!󆗓Ms[!&/E}Bv_oj 6P}si0#X`Bi8j,, pds(G:ɨ{ SًlēL:L%45q쪳M!'|s%eO"KV- i];Q']P'﬐a< Q5gAx%,1o5ec%yk;-~ k>2PO_:FO~;#ЮtFr1%=l´:]_7@CCeMxu *p?hDBZ=qN+u] d_r2<.̟] ݈fY.Co#{zlcCAM.|\N]P^~Ȧ',uj!DX>srH-S[VyX{d\ S[hvYKm { nM\d]ΣNjӋAb1@t8>`I7:P;qibKp| fᑰyר?_#|m(I~~- 8sd7. j;e/CF@3 =qb~)H:dZ-vb?^>:Qq6GmŜ74\s6+ie>3=hs1ﴔuX8:BEՆ$XbƢ#xo%R뻾 mtMpfDZU4/C$p1.y hf3 k.#L$m #򦑪&NEpH=tsf=2 *.X5O(k`cfj> &_p}eLZC$B*S.4u<yy=*vxVq IwΏ1SwbMo$x,Q;oQxjwwW q\fOtHM令=I &m?qVu-i vpC8igH!zlYPpBq<rKH3 7%I*q-=#A(&<ٷŐ ^.г|sN0MݠoH5;NjQnUgśH ۑ_~2`s=#|6xGaדwف[S;SӚ^쫡G" RQt9{k/٭8" (2nR-kTEa437Uq&@bT *q+CBpGZoBߔ! If05hUEζ؏ HN<զ(C6J`Qq]GUL3+Ɖ`)/$ { hq`=by3ؐȾ0Zal!$Ïi#k+-3F~Vd$#xKGA0nt #W&sN(j4z؉Z NM}7$v]Ԇa?lYOF tD"# N֬E:dW–m^rbꊫv@Ϲ):m…^z$ـU#)17)فN"Z<3pwkBoMsJARQF;%鼺f#}~+r<pƇױAĜ3,L%AFR-}?hX` nл&dZ ڡض5_!]X1expHe!qcۀHe 摱7PE_MR).,v UcZ9`<ܒ zA||n6р0dz" óx7K*4oYB wtiM&_'K q *uyAWlҖbV'>dR>ͺK{XqaÚ;"G5VU1vW.`̀P (qw4A vvO^lK Dsx_*BEK/$b Ƽ@D/ JSH ~l;sq?(I,ygC H aqfxh@Ro). dt*{ ' y7.gEQ 1!6Z)řx=*Vy*@a)En҃cB%3B~SV<LVG5m>T:\a+-WLU6탈.7N"xK/:^HLdMPu{F DCk\")/j$q"H+Ozo*n-ܫi0V=~zw^($)~xM֑6"mU$NW-6؂sl"X(bl^}׶3^ý1 /BYT5FBk Xl 70/\[{4d,1gYbN5y`ҋo^W;,o&&U˳E돰փ n:nyZ5O{K?9$E^!,=6C<H- PokHđ&bP"HyM7q$AW N24>0m4,fjJM[O i]\?3>Q=)  ĝѥ_HHfU%=׿)̣Q^E NG[6vf8iocV ZRu79Wcij(݌G^C lVݭ](`/]# ͭRڭ4^Ib&W)2=H>W!{lZKiW]?n.(񄱨-r4S1?|_d KԐQn̥E[8uTkZ2wj$)ST]y=Y޼C;k h"[-Atq-4u(jUt @Tj23/0co\#sǴ/B W"><_ 7^Rֹh6 '\wh ?(~̻nPuVR`,Y3o*܃{WK҅ӒsHnGNWq_4̼i]kh1N e6O8H;7glI<;~]*J!`R؈X`* #g1lV!Q*B,99^?&"W1Lnt`J*u.^ ! m3R36:8. Zڃ4bj?k(YS-RVs˅%h2Ycۏ9D R ?q3- ڭx>R6'͔J`RTc\rLZhJp` e^z'h)0Ҋl+{fJt] ɂOecaY߃Ķ@h^RPW_Pܿw*lBH;3T:uYM &e9 E?*wqGЇFZ !~W r,c$CRƠ`ض=\`r zd"<_xē.;RLT7mo=RPsk8n /}{I4 Vϣ Gqifj{ !t@ y/Ț;F{*WpCW3$P+&,hMO!G' ֽ}6кLPK)O*(ciJ)v)Fo$eRG[xùFSߊ)2FIB. BACH2WM,TZɣiZ"O%z?wRnGQV0%aJ,bz>']6-RvԌmwAKſ*f{%] y$'> ]ePxJ&op?f=d}|}ߢBYLYYQqyG<*CKij; he2Es4jV_ψk;0Y@Zn8ٛqe+T~uVv -nDw3h~lEŎsT B:?TJB7F}qB+lCi4H/ύ:!2{=J=;grYSꜛDE!¯@&hGi7q;͈ ޒq.e%va}.?gP*^r6[Zq+&VFE Q(y@GeMW#2TDaVe1daOpI^Zp,qGx#F߉Ooi|b"` ZO{rcEaM"N U*P`Ol}60ÜXf9\"l_^`\;õV?;VGG;ǗqlQ9;Av?OQlZc`+;1v9d7C6"H)J`1ʔHҸŀ:3\at(-в AXyYHqOiyPp@0ǹ0Ν;)AMǠr|{͙Oʈ8( =¼hVot@zN#НPj6~whUc39T+$3Q4KS$9TB74o(̄䀆S$ϮʰT9u3ӯ*Syhp"L fy*T= yD6ya`OD*M|w1Adb c }A؍TU&J?l+b悼ױ-1͵6|-29AtbÎS0 '`%['ՙ[FO@hʦc$u _ǗgU~*(y1#Y Y7g:uƷt4T&n͂{⹢->ĨlXxCuaG!,Q,-,:>f]Btn?KKg,23SNH4k#ې-eWQbM 8\b4&hW+篓y[u3fFzCgC :k//!`3P]oStH > CQtmk}fT +r?{TiRT^-︿b^՚_i>/(+r\j[N'߉W0ڋ 88P`)݆<%bزr |OO]pIqk}L.DJY#|킩ŶIFߴp?͖X05Шf"'L8PV+kA$\Ŧ0$N^Q4Է\1@= F8ƶT(O&Ml8 P`ǂ,?**B. Z*Ţ8LFNE˝~>ǍpO6Uُ9]* Em'q|ɀo.$wRQ6>PcS!@!T]{w;v {t@"w^<k\YSSdLa'W"v'C m-CnuμpnV77wqg 1[ ^g-wٵ!hu%+`7yƢ%1"=YX'"tz`!ҥMvg˺fA(ꭿ1o#RsYƘh 584Z·lvw LY!tY؉I>Ȗ|%Jl '*[ۘ-BG``@$cL2a7zb. $AZo"R .^А*' M*r4!-JS9&jEei &cd{IW `_s`#_]u! SN&IVAga) E z扠fYݓtֲ'Aw*lꃘJa "Z%x/, ezyj\@Rp= j`zmC\>ϳnŜu~XT "cE#H1n2K;K9>_k Si $Iv` }s>/d6okm&`ET̥KOw]&Sm{_xEZ˄\0.)mϻp_kL~ߘ;dȆl/M~|Eka$"*=8hj2q+uzbWe3S1B1`SƘ||U,l m-0G%@wVp*!eI^?WS2 ,Jy~f^3_5iOνކAjSƒL(l]{4^!|Vr2ܣhT:"\1ct/k[0X/??bb GJj> dJf5\he8RP)У%'+A* DB &s ke|7luLl-]1@/%["ӒҀm9ktվ^D'{,{%ĖYIV Kr=^_\#h? HDsw=wgi~=$ P(h Jo~I}*)'c : CO0BBORɻ sC ץ^ow6]&UoDhȈlsV2Kk]ijL ?_Mijo}wiDC[߂Ƶ9V,0 &[w?c{ϴܕ>WSl1- G+2ZfwuBtP<7 XU5waP$&e0Qgv05xtcfOA2r٪|L"zIdG=꟧zc] 4㺪QzJ_LV&g -4]LGİc- JrY˜Z@B-*n7A5ʽ-|"ABw+.q129gpw6ʱ7}Y7!m6Q3rЁg k` :"ӇMD aZlM^R )ankSFB-?>II.!d ..]`]le>ỏ|ێVz{ q R0.b[+(9$K[z/ I#J3!Qzװ"C7Spv/^vAlŠj0NG3"*d /v㜰a~9]Rz=<^$9b]̞zy%oHM w="Zq6W& 6pXIwi9Gw*(t~`윹\(K~JkW*r|[$t=Ŵ}X Pw36l-B8l.gtUcH%3zƈ@ǻQ?{''8^_S5 *"ʯfvD~Aa%>ƃE8א%s>CcS#x7ˀ0BꜤ 2z'D S[ۣȒ*['b5%gэsZ +m?Fv =? q8,9±+@pFPklՃ ͋/hCJj5ЭV=h޿*L !%̡0v{=mJDw?'Aia.uݭv/IʷHbn?DxMʽ<h-nWp*Yq Jr1,g/LM(M䢯Jمǵv4,QD^}XeRqMGE/0*Tέ~qt3!6|ѱvtxP 3:Wo ~>-9\I$BJ;ś-&Ve{OP;f"q GL65ΖI%}4dsɕ8)^+y`'Xiq ƠKvh626pq`N6VwKEO`RPxTO 764{Buq7?6Zd@61>OAPM|;Py w­i߾=At*7w/Y ׂe+nSITw@Jq z$-MP@Gd%DlRszLid$$Ÿ6-;lԤ'U,$&}7*i4O8Pq, պ^rs 03حJubj//tn2biM*-w&1#7WJ{;o\<+'85~6u;FAƂwͫgBz@qb`V+Hۉtn%<"pO%KmHd5B<%tezzVgZ,uݧ7FZ+ɍ-E E 1{or.D` س+U[+v‚>a=Epxɵ !6LY+8^V.J|RDZL oޢb -E_ZtI"/UBC,+vdU-OW\ G"BQlH Q G>pl0d 13,'Z9LIR=sfʾKiKh.uo[Ϻ'aswg*ρ\~hՕB\5/1j/BJՓcĦLZZ$/&JԒ,cPTr9^VN3eOlQ^ |[ٮhķ. 7b\JY&>xmO6^DM~myI-ȣ޳+YXE (VrBP\6.8Gy)؊%6T,neSGf }ҋ qz.⧅l"E\[W dRC*?|oR:hbGӈ:TB+-Ɲy<1DnY֘P.WD!#ʇs(HANkJNDoc( MҡludmMTnOk` 'IJ\g=Eƒ4c@Oy[(yOiKN;$[:t %_UUgv9_^9IaM$IQ|7#71{|VZ6t J\w#Pڏ1PJ-9%9)@K M+Ox|8 KA<^hòe^hx,]ҏneX ; w;9<bffiB󁪛tJDS\z#Ne}uxbMeli".Kü6%p|* -=sMuR|CǍ~`yt EƘ~h.\)XuiYe)]O]EP3pB+I2gqW՘֏B@t;:$aDk6Q^<Gu@E\%j$I=`DB]] -Dkxw/]vV1Q>mx#& |P΂5itcv0fJ,vSSjyN:nH3ML(F6* 25n^loP鹒=ϓ%Jhᅢ8HŨ{nA2D P`Z،؅j-*.9-Gh_ |-:{O66E肫𚯺dE 0f@]aW^ k5b#r b&G1I듨GU ړ@t8Zw0#yoMR "Y-OHjyss53硱~G3ǪFݤ@Yѥ()XvNژu ZkXEB+3Y!V8oNq5Q3j<"4̜R.'\5P2$Uê/(8CKAs#R~@{X\APqp1Cz`9&=P.PLGgrФb]%ڒ< X=vpB`gDĤz8$fUeX ~xmlDk:3Tgl*\o(]Q_yVAҤ%ξnf.KP3)Š&!?^&HqΎ s0f28O#XyT7mǗ0֝kH8i=x>gzi|UچuLC):@ἡu+}%U^vj IQ2 Pzx 7y,U~q# Y"wG_=DG[V^*e2]雫*TZ3y|3о`%6cI]qڜ εTa4J^{9ul@Amv0A"0=xYtkN `-쒱  x1cK]q0Xta'5Ϭv8)\=/D83zej] ?&dq9%3pBs1w}(JLd!gKiKu*9H85]Vkp_Zu_cri'o1oo'n#d˚2 1#νW?Ntc=Ñ?hpǬ;LMvq?:9P'BKt5;:2ąOxi|+-ux1@i;f [Bz湴Ӗ:?oH`Q.` Xt;?ƮX_<.'C_? Cx ͣ }ii/j'02*iN֢٧72tqRV4d$+]l䜉JWoʤ(17ڷQVV/^Hﶙ݀`KUue!ߔ|:CS#;?FGStI7^؁(T+fk靀`nYrd I2#y ps}9} <5 =1!و/y:Б X ,rmE> {f=Pi:%&C=q3x 5 okN6J+5u!['Rl W2Z%zO#^JP_6w$aU6 {v z4ޣ _+Ks*drNeGQKN$.?^j^0G3h} >#MIv@.oLiuwFx<;ɗ.PoBazr)/?r˪u8BIȕFMh ,(BՖB@IB"n5U4ܥ˜GoqLUU׃8$B`ad&UP2izm/g 0ˎ/Vh%PHܓ&*5~/ Wǃ5s$uZ"(ʙƣ{K+`_.8C9ijW>ǟ tl3/1Ia#9s,ې\\d]}#˚_yGKpOv K.oT:b':>%s&*[mPZdKcٿ8󢕽|{ǗsIDoѤ3`W+Gv1+qUws`^P{Vu& {,if}](3b /?7ɕj pK.M*.o c32e/5y|)F'k 1-J+񏠖kqܜvS$HT,dIM9t֮]C³R}L8pla$WS EnV$ !t:,liPCp D~Q?Н)e smv4>zj$ ӣT!l!Wft|M'{1&H \}Ѐ4[h:pP' T1́831jJkr޼,ܻE휛jE)b o..ZCFq*麾=غ#T(Й =0-;nM5RNƢ2i -| X*|%6B5$fQ( 0EJ;%UPJ@({WJDUk7 y77SXfy8:N+x@wV6MgRvpIYt}G(j:˛#5Os '#9 SM#ef>)3b~c1@ n#;\ DR 3ނှPlĵ^ 4ݝ,st6 _Q eM&د''".M&)!M#EUUB`#>9j[e.ת[̺X/q%)ßr)b|$O]6zH'loYֺ&;H(k¶a#kޢh34ka -(yDBIf R rva}:D~9ZrL=$'|]Hq4E%XF} Vs;Q0 ǰXDc\o'9LptDd,;J @Z }U]p3'xBU41 C |эrq,δ3Hzug?t{"WvSպЫ23M{Q-^8&PMHRoWf\~,3ϔ$r05=z}#ywW'.`w9C{ ?|w8#OЀ^7>BeoL\vcRp'͘C"Z!OEލBz3y6`dCPLH,zn=e;tG>ZLH=P섵߷ E6 =kZe 5Cz MuC?$@%;:b0n@{.4a>vrn97IÛ9 l."Cx&%U8V`/aZg`ݩ>)XG 2?9&x98pƗ eD4pL U %t:]I8'&%9|8NH>LP=xYL\M3ٰ!A.b^Ts\6KDT H|`9ɜ* Celo0fz]M|LFO<=ST:yDEyFp=TUhSi4oe-B z0O,>SjOm\^EM<>b%ϐQ=08r "~ߢ0s FoFmPqllȩDq̛- |A#Ih-W\Ӥ\.z1c,ɧ14{VchC zi+!hk [G`8w:ˤMD`}v<ʦL],npǵ YJQ;ߒχW8Rf~F[5)'ۏ:d7N-~HҔ^Xb ag%ѿ:qV;Q\)pHu\,g7Y{Q<fBQ5Un Ũ47nڞbVj*[\=l9edX+6Ui5cD[? #S4HJ5+$y->TLs-(|7CDTM4w Sk6 "!s_PGظ眥mè4 fq 7yoJnx''v*>IJ+jd#BUzfV;T[Dă<gPWrd3۾$%8Dd_b67/l*ԭ/H@ހV8k镇Z<ȇErڧ.z4*?g"п։F 2YISQ|69..D/’i?>Y᳋nPO!eQPe7+[(n}pN7tE˛0N`OoP)#(Nõfog울LFp D%xbX+uPZ zxVA̹;ß7w3 .^uσNW+#yw4hϣi&oV k؄6H lX+4w #+K(P<^M WG֜5?4 OUO{~ *'f&0>ҨX3d:gq2$&HN-/\sF9`鶾MI}ګ 7{M7$`d&SO@3 KnUE,BtyF>tz]p@SG[FP5=!CͯNJlB6?5;-68rx.nSd1ImsBi]*є)`?dA1?\T%= .2Ӽ~qLI7mܥ,ڔgzYTXV~\. 3}ϵ)T4hX E cӪe,S'j+{!\xnMzYwzgn6:$7\oB{g }g rM롩h(dHZs4qZqĝ~.޲UC3**?EjwP8y+p(h>C/S_O|o_`~HD6 Eu"PiyzX|p\n_2:J+prč拜=R? ˌᗡўq N9pu0uxPuSzbj_SY# ?a5dRnEbV+P:(D,Ø+Ь$E IL6unP?8T2u#1 X%O$_!2\5}D,ጁs5]&ѿw]KA*mWP_/|g ==PPaطYXu#012Aޟ_j]Ff˰Rdzj ƃrn1Cx_cpȐuaT"SK_ _X(֌%ǐqgkl^*\$.=L2y[fHfbH*ߑLR5nTM6K}_(jXjƗB17[!b4녃S{M<:b)^%?!@nTa3Bib]/M)n<+[©@za&j-gEAȥKOW( %2歼rI+ _X,F$KM4Ű+|)_Z;ӦF#kNҺ p|F$73+O팖yY7+<#rGnI:vh#I`7#OivY4&l'-'ְH$*#Y;m듥k0`~1Z0s쉬|v[w#%u7Uċ].et^e2!3  l0MdAފ%>c*C!R(HRqzt&+؜Py{rj*_1mڡEmXa6eDևO_= `d@(z)p5Lb@?t51l_?<~zEWAb8cJq rY&UAY1U@i+QJχ]w"$<:SzS}Ĉ~ G U5f.h"-YV԰<&Rt=% eb83>_ 5,om]LY9cLwg3NO(vdZvCĉ/E27K DG0yP 6mx/۸Ƃ iNj?lmY%h.:H%w`c= 7jUՂT:HʄZmdOyi qh! `,%jM|S}wՏD%Q#u6{,wS͵w[EϳI&k|wA&Alzzw;jx5-*ԏ$뷨 [譜dNhIl}@yWZ|iPd k@LвU1wpŬ8݄C[RB3|v9R8㶎|/*xʟ]`liJcqy!?_Z^+I2|Foc@Kf퇞-=6Uκ?(skS6C$ͮm~>h qYƱ1QQDqeVEq3-4@CO@1d>;YLH1&MvwW f4xaYwb({oY@[|bF vit@a.|eהh1vV+,-mBjvrYd GSEgdIly:,6<Qc,-fhb,UK~s |G00eZ׾.m ˑdB. / sE:ęh^խ⇫Ah,זI'}R 9}}ekuBС\:h3|̰&P`'Hb9QR¼Q̻۠Ij4]f""8|U[P&b +\ߨTJ߶nVs jiBF1>?4X宯}ƍlǖ]wɴJ8"IZʍ9Rkb]G?dtu4ÛZe5mlF-۟Mw͉Ǐ븨1rT:mh) };4\{ rhI4 c!Ab&R0D HY8,okx2pȇ*:Wf /Og3 y{,UmFエɜăl.k cf:4#8; [nMyBzk@}9iX?yHTcy'B *FN7KW ~c FCsZ"Zv EZYQlǟ4RK t\2 !Boۙw(UevP?{qJCep@ӫ+#Yo rۨ,/Oa~̣~z_gQBfznc5JrGfadF%$hEʥO=k$[A06+ xw>OE4:7m Ű3P]V)/p@?vo#MtMǨ6DrMؖHV +C\{7Wa(֑( pCW#^tL 'Ʃ:]jI`91By I,Ձ6$ $@h^3 iVD.UtߜnGbv+QDYMwa%jʺw9fL&+.%ƫtz΃'b!SHKšOYN``%z]?a͙Hm3, j1/gA)Oc%2uX\8F-@ vZC-)jpN#_}J*d0aX:$C,YYu'vܪUl>EV,wR)VxEڍ139$a%nTƊUl4 )ׁx>b ~?)03 p8+*̫YU"].BCwd>Ϊhszهg2`pZc,+FaG"-oZJ(:(y7>>f]6cُQ-ӣ'V61dY)ݤzgl*)3 2 ICDtHB*[k&pp"EX(MM*;dbH?Eқ@gĶgM9#f~?V)@R xB+AZmš]AWMuZX1(׸HK' g/4i~\y]|͞c?*9oMӸ&qcC`jfU8Uǒ}n^lFĬ*ui]ܰe⅟Mʇ{Pɰ(U}Sb[I7t2z]F1}+#x("_ ZfCj |KRyc($=g#< >5q/9T{SqOfھ:^,xbZΔbi~}/{H&n SxW5*M}t%T>[#v,8-&gHzOΗ1XV_&'nؑtQF[_ vF4ɩ8\t %JL\QIQ\]́Bq4 PkKa jE/6ح ,1k I,{&"sS &8~NbزX.VoVz#N-*LVӴp.)̇xd"@0 H6eSE#mkˠ@ o0h';U5N/VNS< VJ4adيSPk!2 L\4BZlRHJ3H*[Y c|e.%y< rU=Wͼe1; c8dPVqSY"rMp!Qi`U7xgɭ^/49wp _1 bX qJ~ ^F&kE햪5c~Su^gN3%Kt,(8 Gth^/ &H.˽.oz7<:v+Rig.AG5C }Uѥgf|qd % `;Zae*ZjB"xȐX|V#}~Tn|f;l wK# "={(ƳI 8\3~)$Zh"'4WGK(K$T7oS>P[ΈŔ %ާ -ct7"X-d/ ,U%!:o8(J5PBQM|fAXUAğ_#hM;桨uq?z\wQaGŐ4JNi+N݄y>* 4r㏡=hDw7"]zhDBt@x?EuRm*}N VqDX] AcGI]rI'= m+Fvrm)HiFgy<8!_hna,勩c< ZMciA*Bug;qg.hD~ 6䵌">ow߄I cV9y Sm6=Jh{czB(&^fw߲||d(oG@'-V{L6<{nWVN㗬Uv[0i %s7DvpCEƸ+KO}4ڲ@[k>o{(=TD=K$.P|[3Z+do]G/? Zovald:?ĕ,9.i5Z^]X;a%8\6ev"CpCse0w `>+B˦LRF<,n>(r: pk9d4s;s6'uA4ި #6bHͻD27 U9-`(1n^oWqhEˊ8M{Kc@uVn("O\^) ɔ/aQAˢ_J"˄ WmWLBw^Qdf9NVh}ddQ `*{.ERbҵN#(ƥ4\쾇h"C+6<V$4""$ :bfT~:rb xWbuuۑRUbz dP0&9IUH5؝K ,pű/[5-*6}ƑzgX`D0F^%nOHEXmbZ $cM#4q?lfhF鈯ew'}{Q'$*,9h>V?h+ݪh=q6Vݏh wWp4Xzz=5$KnBԱ, `񳦱ȅXxO;.SRȴPW֢6:1zUVΪO/GdhDѼGh(ۈ$[MV_.Ğ)a'ỏ[W Y׿ ]N/H, =|Y6XuR1#4N4g7gM21W 42LB+`.p挊:pN vR7{E9zVfy)%yX\mAuZ^j!cF-162R;L;tPG1}&*51ٶٕ.}FF nNgJc/DX wQ݊Vq?l @ד̇bpm/Ct)oڀ%xW#!w.neI=t3Eu]C|* zu.y=4']9!X/#mWd',y[_P.r7o' bq%G%LJWB^rlՑI Z;GPk[߷C]*fӾWD $hO;0,ϩMYK9Z/fS>Qj hxڝRG.@ G#f5=ήzL oBJ~R5%Y9ۙ :r⥆\h^x$|o|<2$Tl7b'(O{UU, JW A;+ ־F悊74:ѭCj4'ٯRw)DΡ*+ A#T rOq["t`b˘ 6P(j`%lդM&Y?@hH+vU&@RkP;t-RޑҶ(.Ow<=FPߞx@O$b#WxB{3+= ь` e]ȩ飹6/? |XڂU,БHir;T]\ʹ̱'HZ?^/a/?g^q Hvl'\+NjO6#ߛ_M'P,?Guϴ_H `//)Ncε PIHN)gT!m=uahʑЫIV*zXdzjwsjr))hW2RS' \jx-0a yBs{C k`| ,2nY q|ZM),Z D̀Z& I,H_Yc\尐0 *쌸/l3B*j|f-fJJ0JK;N /`k jg[Y R!BH1<`ߩ_>apAr vRSBIsyD:]g9 <嗖ٽ.I[~H$[_ s+SRzB+G%j-P,:(+Q1߷(z23 ~otc9'NLzM=i'>[Uƣɨ2cExtҌU/jHj xs (׻oaKvĤ2m*1LU,וP:7i?RgM73:$!63)2cc 9Z[9F-Ymq1%E"n0~*P6A#iߚ %uAKk.^ΚR-eS T|x16fsjV#shS5It̶DiA0HpLvEL$Hgv޼ vcg郒/\UGYV+]b).W[+CN [̓\+Z5Wѷr؛[Lİi+r8!``+\[0?pxzR8!xu\iVB;)ҝC>r s93]e 0T2m:uc&.ҧt^3<'0mj3;iW3tk 7rrq>Mu <_$aP>GeN`]8 \Ql|=W7 +~]?_R'ü{!ݩi> G5 ᪘dI/qbGʙC[MX(22_6 p@x'k8a|=9U%JXq54Yԭ2VV3Sͭa]\bn()iWoR=lpFa~*O[fUch-B שd_>2!M|΃AWd ř x{%źm2Q#mʖ$!+ ~끜)ZPy} d5sF㒢E~xDhΙ]ZSRk^~b*.̘ &J tIDci@?(M1"yӓYAqǮyTTƑ(PѸF봚L2 P3L]Ɋ5lz3S -z9.d,%ź:ji1\؊!~`A=溚˰wjy/oEsR^_Dog_#aVs/ʼn/(4TMMoq%übÇޙW{g 0:[xֲE2㖧 B&*; ~LEJ@Ϗah/ `!QBAX=2f#OjݕŽfh n#rAjCOn[ZY iwc @5|%h[y堉A5m5WќX lLn|,*qD )HkÀc Uv2?&OCxں|:O+&irb@S#UHIEpp$hH wabQqsyaO֟U> ,^b޽#F<LPhܨ1n8ԏ"kAP ~%M*M20Vnֵ[қI*no{v>pV{DvC:y:乒8{CGv@YXO<-gfq䬸x[ޚչ]~6[ȑ]_d"!o>r2aUs+W#NY7Ђ~6%a+Q h=0@z^=hk/k䣃OiUY@9;P.;PAoGjE$%H3 )M Z%%+Y{my-qWF+>ܠ֍qgs#Y[vCaK̆AZqkSGj: ^ş麆W{ :_j0 ^IJJPFh_t_jXB PS`_ Z; /uў"`H[&H&jg_6Pc!7a@㺖6@;@+qH viuKN-L1I b s;mB[hkwMH4#6A{E6:)b & `bLIĉmC*WZso얚- ˵3eijއWG{x|:KS#=!;G YCLzV0X;^U]Y!l吟 1B#~ %"|MFX%Y ^4sQ9B"%GwVW#E] UJi;V<`B|8+_[D6!k =B$asxB%2`+si԰]43ˠ|ظnd5F&b1*~WZOB+RHNؤAIO*G>A$]^wz> A9-D9I1^kœ;I9gr7Q= sl.% %TOD*Kʏ',$&Rfg,/I5(#tWGM$P EB- ԙ#X51io*RQ`+ɫQ<+E8c22`5r7H |:0 ?j2cl)8>x^7R*-p?۪59r(6dPVG| I 2;U-\cԻo󲤯c-yUEp]szyw]'y)&#=ʦlAF6iP*gӽ|u&}§Mm@a`+Eu[e ҶL&$ \TǙFr]saiOPS ?@*nCEʒA64kẩ]}Z7?MGhIN_I}iI1.^>bZF kU9|ZHAc]> W n.hB9 5c֢ 6kY 6apڴw+ous x"Yv:dMc6rIiRY~y7➎zrMS.eʷ79 bO C$9bSWBsߐAƷN_z/Jjyu9Hy5 G!}I>FJelVLY$RPF`' iw^Yxl3@KLk zt!'ȻWQ>vwCM~eZ^#&\u ge Md (9~e->,A~ٰ;Egϗ? ꬛5^"; +B7t"dcOQbՁϾ |5003$xU黎}#=Վ_Xٟ-1;HmRƆJJ+AɴIqMѽO`AX"_թs#[/^1PZT8;uJfWSY$y,L/%Rjy_ J ۳==Ng^aÊ":'f 69wV+")[ z{E=z:rz̴bBALl숨1\ִx7%O~Tr><:-p8HX#-I+2.Pec}%1hhr3ځCiH"S؀1qlH#ffc#+BE|֘)F{OuF(μ"E o.&SvQfdV m'%";lee|Ï^XE($9nykOSòU] tH׆0 \npExe3fܥdp6uͥSGj-I[},籂8/ӹ!BV\8A}yۻ؈ X2.Lh%~҇Ds!"Sm}Erg9%0#߿A q[2AȾK*]vceCVn-ړZl%d \fO_! {ڀ;+%qk}_)}tvkp%8#m R"@-ºy_4ѱ?b(}Co!'Ob!vqJ">\pS {IӲ|ñ5$ 3rDAimUL؄eKKv'u/wQ#g3i2fQHgTJ#YZvuIjT}Gqܷ ڞ4~Ǖ!׈鐀V/同py{m+[ |4+3${Q?;F,8)*^N&s~`AH@9@IԦ {\ma9ɊE ݺ(ifQYuY3{:<>B•x\Vf a3iP]`j2͡oحsn@w[vWC8cĀV[q[\fgPaÜ2tb2sS^u83O!gI&lkv;“PIIK.LlT b2ge~##$qIz\+ /K1$s:Gњ%cu:elH .ol{1m m@ Uz6eɮʍA.NN.M,ħDɸUQ$䏷Vey߰[g69yQ UMEiX+2T+IpD+WҢh3<FSۢE|U"bv SUkTh65G`A:=&wF#Ս ޹J*h̻+NHT}{F{6m.ʑy3xO ׏`_zVVÜ^Df{^хaz* j!&}ChIA&g?*ۈ]=v#t6L|ߙAykƫϻyk(3$<727:n{[_JH5CQ)Ѝy,[Q!xѩ[n$ovlN%BǯX75>56.}!nx"ƊD~iE↉0b}I ǥ*zG [^w 'ߤp𭊪^c?Ec< P& 1_=c3$k ܯPKg/*$ ?p)󆵹huBɾv{.ь;O7h4ؽ-_|ޖ@AX=+Znտ?99B)(2q-HQk|jHK Cx{p$ݼ#:E[U*[ѣa_ێ/=MQi<21t3:#L%[obgs?wzv/~sP{?G%,KZ0n+>Jl,Y&|s>sbXCdnSHtz1$[C 92*z(&< j֋8 uv r&߰_.̆cWW_'hU|X u_>)ڔɶ*Jt>I@BCF@碾Uے-QEz+2)p* -P$ UXR}zÞ&@ƈ=1Q$K}!T`uh m6QnRКE#GUV./>UDq{fZ \,hzxǍ8:`h`S,|MrljSreGs3V/UQX. sJٖGKppҐQ!0;f6pX}8,Τ?k.b9/.|\5Vػh5җObHv42> OANou!Fk PLⓂYs CWx;Wb f=Ixt/8 2]E,$}O+P՟ZcɨE蔌#)qF9G0?E}ݚr nrw'8!1[2[EѴ~5c0(;&&]A&?v y]-'hI٧'xy{66&`U z];R"xN @vsV\4<Tu\#Tl(SuÜYu?QA\߂p궢&:`ޤsX 52J%)olmsE' .ꏝ*NEPf8BPlHJv!4K7kdUY&;bb;"F~K]`iO '"CqaAƄ0,F/B "? _#4Y>FKp/*`yB g%x+ldI-E~E$y^5ygWμ7=+$ 6~n][>"^u+$EMM|v'?-6GcG[5دx3#ka0@eNK%ԡs> nmdXܢ_`g-A9I={y))?#)-?c 0ݜT%q*grXRiN}'Q\z$)!?9g;oC#Y7ěD.f .€q4[[dL G5WK&5!87k4<>k,BF5[<Κ4)%τ␋>ãѣMR@ oрRjs?lV]7#$lr=PWWAe>y Ȫ}0C*8nx.5BAr~* + Hm^)L]CYO(KF֬;P XJ1;zcjuM>ͼW15síF/[s~:jʗ9\x NW8B] !ClB/"vJʬXMUQЇluv8P| -0Բ^ Rd.ƀ{E;w3=s[VֳSٽeOFwMch~ros?u5Gf:g7lXCn( !=kZŲ.*y:) c l]zA}f~2z<D-YXZnp) 3+4 ^ׇ{ms i VBLӼd;Z@zcvsarݟeF221C>Ir, Bm?0*p]ج:%i^J&n jHywmtF{a%H'ӊvob" Ԩ&?MAؼ[t68 lV J+Hs9u^~m#J# V}#|A4K[İAS3X/GW>L!&y׃Nv}pŨٽ鿶mlSJ՞oʁl~՗L@E]ŖdTpfs"|0,IZWAm=4"lonQ.|o L[K]W5{8cuikdTݧC QLp4pl9DuS.Bo;_%nɲ!=Ev!]f;~4&dS OfC[9ާpz4B\~TrfW[]rl7Yx?: †BtV٩ZNM⦲Vy+hypCLJ@l,=cm]%(l2_ bd[xmP$*[ ` yd]fFF HvJ{SԉPZw*R{H&Ja&Jho>6]B$8bBPXYؔ9hY4G`۠9R0t+kLr?"ohtu$Tr#ίg 2Hw+7"=U􏀝. A8z*x3Ȃ$OƖ8貏 -ɸ+9ryûB_S>X]i$"->Qu)J9[ƴt|Z.ז]U$,C+I?YXw+,qepeHV&;Zat*[}OYάQBS,p5nEN|JԠ+,/C>1 gKlgp(P$ϑ3)"g VY~m3iAGg RD'0IAԩJ1W4LьXIz~O%* ٗHApKzI rww 8\m* ;;~aj>d'{tn\4 ^.@҄j{|bh-)>Iu r̙(F9+6ѤN'~ 5GW5)d9o2clpfvq>YV:ʓ]@ V_) =9elpJ6ֈ@Fel>ܡV_h/n[XMSa D5Dz_cc3slc^{c̹e΀ 5Sc w0 F!)\ujU*7k5}j8N `{hRn-WkAuZVL 眻_( 4y f$J?MS3;>c} r1߸SLxҏ(ͷUҸ8(g$?e5+3şYƽ- IPs'O{g}rhWCI2m`*@ҕ{iYV?C|Z"͋1 gB{WU%cP*o7 G;Wt"am$9ޭU# ڔFSdstR Gf&_=U~FB?Rq1KmP`$KBvU ѓEx4՞d2*QctTt^Yڂ3)ݧE=*fv{`]?W#eUfPp' 8n]˘ ᤨX{[U7`.WW1/2"捏J=XC]E]$5 f2Knҩbh^u~U=V@3gɼ)sqd ; _9K^Dj|cѕDLG}ثB*5%:H5427{TT)&M[tewӻkRV_*{37/"5wRW>~$% \D+JP[^bNR-njIbv}ijyrXAS Q\$iG8ZpG^]'-՚'َ(L1'+> lw.| =zAI]kUjk ,Z3w'͗nh,4Ss}J=]F^Q)<$s,[3 `k \8!*k '~R`pD]pCPM6'UF m`JbnԡC)4W\A9(!MFK\K 5THJɍ^X"?.I0]"uQH ƎŲ *wiZirY_A|hHU@u[N=o| 0JݮE`׿Af54bGZ$anS6bBs NcX(j!sϞwb Xo`?y,GTҺa̭9ߊ.~84\g31Gr3 q5<Qe10ۭ9bډV5ǂgSW!jtjL+cq]2*fmU ?({e"sI%I &LD0&(X,΢E'ofqʊOxXWsF.h-l2d0opgq -Q Ka é}QˣkY?[|M/AW|M=rZNjv#9"Hl a<<f^;=F.0F;C? L z0Ͱ% NR"axE#roSj1KdS9ͧ-}[q ۡ3W 'lsՕZ[?؉aV] {JXP"yE7r!d,@Q)FY xtvsh,_ 4Od\ʾA}  SHMws/{;0 M=&_FApZFkC=RiM3; R5 b&7a#5Y݅{#LINŷ3LGsnB[YI o19hILM?G06bx\0G<I*7se B,g=.F|XSS@>ɪŗgI$QG|=#W"E[G@mƻ X@@Mʙu8˄{A;~؛->"\y 6-HMʍ&_:'2rlծ{"X#%֭AgY}`P{ w.1_N}(s:)< S 7HV/-aCIg}Uߏq *h{G7b5!u٩kg59]`ut{g#VYtDw<ÈMj wU:!`3K0 : x6 cUҲ.i \L>GAUxXYPXvNkđClBwcB;b&}tJt#8:PXCARgjl۪*_i^TcJ evkÖJ{z:'Êw0xݩFAO华Mނbo~U^c];Y_q_ d =dƪRk֫JmVl( w,TׂE$xM/b dG((`Mmix7W.XuҳP܆QLCVS@sMÞuXQoxI OFʄ'͜V<δ[u}Fpa+|n J1 eL6:|_#ؗn9g}Jl1P3bݢE_ H\̡rH!M30Q=Ү0͗X؈Wn@]7tV놽3sE6_F⻐B'=&ȸ}A>Pbeg &dDWA/Tf7?]La#F9+vL6]C2!@/%O̧t0PgFNReEvxX%GyX`+63/Q1UK#2X c4 ~Pq2W̤^^EAT @W8ﬔM>m|n1Q Dת3&Fa= ;ѿ[NEth]OΘ!ҋό]C0}}$/@3U5qN`5HĈ8v<@{ ǡŮ: F4b;ڌ#?jXUJ5c>Za{LeL7KUBk5t2i#Z烻sUאD c9a@~uA%p%Nv+%m7FA"U&{S4҈ NWJ>]׋k-IhvCύT.zig+Fuز mJ3К_| QD,|V[Yb&cT /Fn?>abcs i=*injE$߬cW&ߵ *c]Tٰ{n}#d 9i{y5 59%TI.Py'e7q,z JX6*r`#5Ʋ|*.8'̏DZNͯīKf.uC" ɢD΂zl Emu|d9{VYeB4]f@2{K&韆tX~ZnEٛqbKm{t{G:op  !Kvvbkoq!q0M 3 3*.tSž ֣A @9b0"?A2C@Hm?vVL,a+wu »Sw@ǩ|¸q泅!cx| 8w#.#!R}$e2Hݜ0nK6ζbmN6rNY-MOPbpV\!C<}yP^Vc )I&;nQ`'as{XA1YL<ݧRfwx2[U] =^=S08}8QT{l"s ǐlLJq.wHU-I8Y e(@v_15lX_&NBB=prL`B,TFŤ8fy<Ԉ_M'KUCB] ;pa}-: Mr'f WQdn\h/gէ`3# $PD@v `30Cd QX%WCe~/> K#NzYap97<h4MN2wv&CNpi):AՃxo E79Յe71Qך#(HlN&w:W& 5yUGb+9'e30.Le}V+h =Ěxh=kt[  AȂA,Zw,On5#rvɔ0mwc |w[=VlcвoIJxl4~ǥ 11nG5rK2( 6Loq>N6ݱa842L!I}z0&X~}%}eN$?S<%a!asoF굚jL&!c{ۢTX~Qi KN(`8{Jj= ~ .\g8vϩ۽tחr{b9>v?, 1bm[ID;΂ZɲrhΣ񵿁SZ;o*4W5E sc8=_3qPq1O6D44mo۽̑$XdChY{PRTې/G@medn3];jjSsmp)j*-OxMYlq"gG:@2K\+VTR <*wk[1l頏wNP_ɴ&b+E` ED]@z&n)Cn4= >X*RKX3rtVqtqf܅uаqZZ&kBɜ  \eon>Q^ n}Fk1jS(9E׷:@GX(d kk\}'󡾉ɓX.YnmLnFx*ꅿ?L$q+G%|WV0Xrq.׈E_.c|bGp*# il]kZ Sz>TчR^r9Wult l獇 M8~%8fVA7/ `H?(՚Q߶xT:Vo݄+X۽iGC5iAgbp! Mp/tTf:m7+ ά? |X JͬYQ޴%diy>#OwV-^S^F]z΁4$UV#fuxխ3x I) };0M ttCC3SNbwb|Q,6PԹ3}V)3vEJO^xń4G:z$p^Δ>kkr$zcnxaυx3淬Ʊ $or|ӥWaC R[{&e'lEZύZ~|9m)[Wq~:M0F|m>Ji}Fy RRnddFbh3`"Jk!ZD-ga!'؂h7$BUuR(/ub}|MavRGDJ,GL^Z(ghy;'G1olsq/ Ht91_+\ .AΕO4= 5*G\H끑hf]tHX^;(Ce;wzشqZ)&xSW@i;`y2o癗Gbo#KrWqHVgu?y@Wa/+\ИYpm̆_rE? mIW`iZnńR @=m&ZAPg͑ 8 @z U[N@3~DD-Kb~Ԥ&-Ɖ QH |xy բP:a|Q{˂?+=BI& R%8&D \VL<-ZH.K0/q:“)T1'ۮ<ǬSG KۧT_`8R(e =t2[ -'d]g&c[/KDξ ,=eZN8vt26nTkH=[^ c]LR鼼Ȟ<>tV{ZsZN]].M,VӒÊ^kU57\3XbHpK<>kX$YJDGz}wsV<\[S^;۷m:1̳+<|X]3p;= W= 8uRHVKun;7.P+ڼ /"LL9(ܭvЊPʖxu@>Wl Gbb ٗ=5nc춻 te"AdxR={IQeM$YE'OD`6` [J m+{]YJC6뙂;Br /+Xhq5v9wM 5oJg:q3zXBDt6? .-fSs-ZRңr}[K16ܯNhVp>j΃ގ#qʅ0 Bކn7҃SƅծN , v-VǔѤ8fg_DY 1t$Yqwj11jd4R* ދteW<$xӤ~4UUdŬ1t.L9j 5K;9na> JЈ].@akT!xW/7ْ tx2,3rX fw)1fq#_Dn| dI(F% _7'4LU]ES g5Jы0I5:g4pMeN,:+4tʍMkX%Bh7A "BYfL{*V Hf//d.'ĝ@ܽ>f52VrkLcB!BUZޔ)6$*(o{p7N50:(98lںC6 rכFިҰF5( #[M>)'Y*ڇ Ec-BB}vvU}:6_7e -~7nVbET[.]G^.1o\B%y);2G8~hb=)\c[{.΂&9yΚ H8(ܲZZ jlh@{u(,]SV| Im4TہsxUe󙈚@Y*CNGcz¼DL^wELU`O݃!2OSA(Eǣt~(P-][Oo©EZTc_-B|9s/堷Y S81 & |-`?=۲kjv whN Z{e$=5d'#:PN%[qriRp^}˵%*D;G6݄ǒ3*zH`K7Y% ~(nYQٜ% 2`}#Y2Q#lVR5>E78\lzR.u&B͇=(IB%(&Q ƈ\Js=G;/.@}DkW'YW?ta;JdBvnӜ0Ss!~^T;2t(F*6ױɷ6ޫVi"|֭Coiox==)b3Q@= S;imy5:jVܱ5 |ʲ9g %wVmjD"? >h+>rLLFzٚa!Ewfr$p7ނ2mv?NWm:7k $-¸xLQH8D̄PK9?l ND0=х|h-Kd\{nr`NJJ9Jplk%4 ,P>&rr0XaE-Hk5Ki/gI>t+̵ >KU^RpUN)jG/Y=}p[d9u4JN<}ؗ\k!d#m;߈~rtNC"g$jFLYOGTb+O6VZ+ TmdڰQV+_4z?(əx${c㞿+>tf)((ÖJ\ koY׀b:j!r,~U=3a^ߟy悯8b4u| ]vΦ,A;XDEwfh;GQfHu`kTh.K2-avVX^Lyk[PXl&0ڡO8@3Ia ]4+mM(xKSZw`Kn!}>xa8÷u/eėC4-Gj9-eĊu.`͍`rخ.㙫ԩD.0IT)N E11hҹNI#l7ug_֌I6gQDKV &(߷7Q~* 9'Г>Q`Qyᜎm['LT/zyKK9*KʼDC`DH${`߾R7qةK+d V !!/4]ks~ĸӤb67Yo"R;@-qh=-hQj@%"kk ¬/tZ@ |lZ 6M$XJamں6]*:DH\K!J B2/An5Pf}emӓyF 'wY"ߨO\ɋo& >6R%|aJSp$ )]򆎣=X+ހN=ĵGNqAmhVd1@-jh'R(`IkR&h6`Hq/5bs!%?&;XB\5rETHpsheQr5y-[ܧ@)`IGl>_=֜7|>OCѠN#~ZE(fp)`0fҐbuWMhY9e\ꂞwD 93~oz᷉ZIȖ Gك~vh bk 9igY,Fiÿ?"%\!w3jht:\0AsQ #]z9L&oUfBw;t`j 97eZQG,r/5Nqo(X@*~uck%P^=o'NG.*'ȐX6s;YL uP5is,p(lh}& Vq_X᝞ z7?v¶k`iZ`HFqvsq xN!+K^+(\nk mSm<m+EZ&ؗb}&?96WGgn3Y$nAF%RrZiV lNJ Ы{SN$5Ō"}wꚵ<{@"MǸB.O8@q/Joww x&}Ӎ %NdqB=B2 sy4p2 _,tw$g K8 ֮TǼ}IkS^Fg(Oxw͂KcI.-$Zk؁Z:V%ejڿ1\D[͊,WXR[Um3 F$S}-JP"@' vb:^'o-ӹ%:rVlzq@nynw |ڳv"__ѯe7ǘ) ?gs5|YjMlk UXkζ[@?R (˘ rjՅ3lۉ( -WگC 8Lozዋ?n&|?ܵdښlz@ѹ>Z[%&:;%)z֦h:#Yb6$Uǯ8iqSl,.,n!g`-|`eI"8#uh2~7 ˬhG宭׹%Ɖ>*fOHZ}hKC .=@{nv6չ-Qebu%bx?:uLAqG6YS _u}+$Nt5}+-nǙ0̊eSGcVSa(+tx}]^ozO"/&?jbzBWpyȤ 3˸>qlbLOlM3[v_(vjyO]? X܂p^@AeKpVD%L>DNaʌ2/bebF ʜ2&KzDͳ@`\B&wAabB 5tdĆ=z_?pi& =ZmQI=jqk8[#9!}rQ«wkS7>0ޫ)} B G` ?BY9'W PԫG_]=Snn|q|9m1Sha|˖74XP_9I cDۏy&6 [4esBm]D%{8WbQ~:,ܟ7Q#8ڷ"b;q6hY_G$dg87GtFWEiQc;6 mo.K\"aC1zr>]W:ԭ_] ِw>u2g% Cѓ[\˜t:2,C1ykoFQUG7 hf|x?;3D?awݛ LS-աHӤ0^#FNCp ^"kv~7C K|e) "ϤAGW^}U(>z.D@&0-[ !_ٱ1_Xfh0VZ-G"#Nb;DMr\BS"> }b[&$Å罚_6͘2yoyyYEf䋩iE6)ϫ95P!)۴glt7ESpYوy7JR" RaAD`ԞygɅPh]61b~kmlHzTB4׎q͸h% #BFj(nP?rtTcNܧYϸ k]R5Ok 9OE*3uƱkO>O 'ޒ{StAnzJSP`f*t[(!DDk*h~&2nj MmΆ/tBNNwg_9WmV=[jUγ>YmǒH]u؜Γ4QS"Xd3O'_F~Nz4!쩞qmeӿI!Tip˥M M oq4aKqyh!lfW(ZI4"s oaǰIgY;iDڟo@[Hnjz?7֪ùK^ѯ^|d]nzz4L;{srΛa<*V\7!ח; .[}Z!Y=tN{krl8>orHy&mv",sY$Ԛ6J|z#iuM;.u?_I:o5m"s½ۗ9+X~RR?= yHAd:Աb$Rn`nN\?.SCr+ћe@՘=r!B'dvM нtÙ5%nO pw6+^\6TTߤ>td'CaPςu,X\S6qR8l^r9}X^ӣ.VD6*!obߋˣ4E҃uV;x]X2bpACi m;g9B(90NSmR4#;?gy 2xV2?=̠๵ f-WU_sM'HqyşY9GѶzōkW;w%&ר]:QP}|"|QPZb|H~69Xc bXF."V,CΟ׊&B  D)ci]=c<9nU0sc"nTNJHiv;SABk߭ ,x5l03kd<{ąZ굧&dOwD4?;Ov, sx+.Hvb~x[OX0?JdZXM ԓ"ZSH5qlw+pzSMR7^co4hNF3Ils_8ҮfYU8"Aww#w wurl#l Ho i 5R9DUcDzh؆Ti(ڀ  FQ8^'lfĩBwSÅqvKZx5+!SiX,Ý3D;w21A׬f1'$[LfMy6X kesh4ƽc'<4W?B p/+ǿ3LctGI 7|Vff%81ۢW c vgYZجm!ɮo(QY3[<(Jc앿7"!F ּȪHv{0(D%S .>X]_,Al`7v.Ή*.p_dtVZK,m4&ȜܦW!Q:qALاPyRXwl;>`CAMh#[{)~~[(!'Y% %m0.żuV!_ӆݫ/t*z pو ם.MNF1)hMA^\cv`X\ OY.)j9ݬ`-q wiLچJDl>ƲyiK 8,Y:a><3|~/?{fq)VTDCrqks(x"B|A;[:(C*x $9m-ӰAê5HU k/>|4*x!оd5jHg5 ˏV&BXaEh^0g^{@ :&e_6U`]Kh!c1eB4p)E+D` fhn /A'ӑV):Q"uo*FNXovk$>T%r2uoswr4B, qUB? ;;q:ZUޗy:b XMܾh$VA´xJi|SpiA69*x?6 ޅt!c$8 ,6!tUHL  :XJ͹/]X5c&k_6>#1tԩ2a=DOBP`P@x)WD Z4`.VIP'~Oes)H^ ]}e4rEvOտ5ڛL*zx0cfosWN͚otDz቎@!E-]rP`F.Itx9yļp.H嚵m2 *2Uf3TzwhQvx]LJZ̀ŊKGE,hu<){>'yu[lk耙7g7vZ[p&Ե ˕x pZ&# @qzk/[U%l<ú\ʭs#S5eS6әoo 9BZ*CLlMH`B2Ikjݵ[_Dhᕵu'Eeue}!&L2QiMadSWb>BTCn'yG&T| %?uYmD=qfHОqj+{m V(4;%MlIig>?crGgB_?db>ͧ{kdbiP@!w 2V{&X.؃"owd+U%͆W24L2͈c/8o#:?<_RKKj|UAT̔(A8?M!KP L(Xtg=#r1Uv6g^]XS*[Z(:zM! %YrPp{u2微E2>T8 ݽ@F\jGG#j (q8c"<+cl'$zYX\qVH_8ױj`.sJeW+eR&RJu-ٝ)3L+[Wk|سJmpޤ) $8,]܋xƬ~5a|ѹ?`Q )5!(jJҞJ+2JR8(;ԂҀ(s03/e?aS*9vlu2A=pX6ڹlPid/xYJӌEh:ZD5NU8ϲRt u9 #Mų @ǐ*մ*9جq9*gz lLH e$Wgwa[n;W#4\דc w47PgARJXKA'6(2D|V͍~,!Gz֑n7_̦ߦv=8|8! 25M QjnVA#W5b|(r f4>y~v&2}}dcX2wS+WHN/{;Ɏ&Mɉܩlӹ]Zjgjh꽹 pnnHWE턣k-Q vp '{dkO/LuQnV]{IlLȻd [y+;ឯ5LփyIo! dG6FMs/&>:+鴎A!%EW_4 k*(.?8G|k-V3* ٞ[f;@[1#I5+8&?_)]ѧu1 iDĞRzJay *oXY ;6xwxPzEmC7Js>,,u<(VJ;S%Yvǖ)Y3-Ϥ<oI3M^5GAf5i +hฝevvyV$BVAQ\Z5(܆7FqРk\~!O<LsJ۱MϷ"3a牯lëw}֍C'h?]r[U(_(b lUoBH*=CU!-5H=?ۏH_^KgdCoe׻$&K]m;5|Y"s#)M/eiFT7;O><3C/q x^vѢ1nD;a<2 ׄwypV$!(W\[?*%j +"ZnԊ]qfΆ |^M̃TY 3W3luSݯ\73&9`ppi}24RB =ySՄ)5!w='N}HVefd)ڢ|%mp^ӡ;j^>?wU t} Bǻr?m&J1GCW܉Aݲ7فI08>?Ki!ҤtG{mYÉ߃ 8'tTPt@!dcL̺Y4͇uH =|k`ɵɹ4(Leϭf1qV;[,>s/> <.c,|U{P %TG絜S+uzyԔ$箥mvSmkl ҍye"5f2y|8!ZӁͽ>j1Y\~pN r =LL|񗺡SjSρkt]kb߾4O8mο|ۯjpAhH)ppL" ԯ3AKcu$kje2trA׈P\{_,]g[>@ @~DIV닉eд[G|CJ1!%{6Zec!yKGQA+] iE)|}]}xce $]@25%堮Pm緳;Ԏ.@.;M0ja3o$ >=C 3Bp(CJ Jf OcFSXx[NR0'y/6\Xyz+8𺖸9|s P&H {䶍Sm05/rN[փcR6Z;K3j*Ӏ$'$Q==2yŠ`试7 [x;T8 Zp4>~T&_,iQeWuDm{gQnN0n-X% ?w-O=Wm˧ff4I3O@gΓ"ø֊D\t.:`Irl<\{snB;v1r虖V}_~AKNE1 oZB0!WxY~jN\o~SDU-]N437(7H֌bmiU6r 4u ljItRœZL #܅-ŖKT an7ن;5p" $LRQG\!dzM.D;#+?Ỷ}WϞ 5DlLsuٺQ𙂒&;a]< IC7;SDذKˤ qZvZHAӞ5tT# U[') 8rgT=߰J.$6fG ws%(q*($k:p۽'s`Q)S0oup$Y'fـ&e]4(Gub$>_,V~8T}_K\eOhry^z- l${QCǵ09dO#5)It}~cW=E(Yf{OJ*9Z{5P~ ڌ*seEiD,{a>uWlS1/z.˜.Pd6LI"AfesӧTjh4 飔;7 q``X^Q`MfL|G0$(2Jt%к ݩʐ2$-]K_h4;!2 6M@l=? ]nݢ$4熔ن=u=4n˗zs/E}x㷺:iϛE<$S@O/8i"LR9#G{mHZlWq7&Fr[i?sF19F(pTZօ2pEp+ّr1'W`_ժE ׅNQUsEH6:a'I? )  Yֻq ѿ '&=q1$f9)-|- +dCmBGy4cVsuW\j"9 yu%$T AlNT۳kC.8,N)WʍۈoO;PQ@_وQai@<ȧ %L]c_ Z=6N}㭊_Oa AS ET՘ccΠtڤM E 8uO8kSfD/+ !zjD-]oGs9 x$FDi >s7u} =͕sJbc.B⁐PfL}c{RD2#)of >H{첗t\Dye˧7`Y[.;+N2SG[3F+Z7 F؎,gY}S*G&vЧ6c;{iJ"\ȦqU%cjeĭU.jb0{C?>~sunjЊ=MQ nE4ĉ I5dJ͌&y!tLk}Gf4Vj)(4^j-cɺyi6Zb]C"3)i96)Lsk ;=6X*Q/QI58Kۑ몿aryN4&a-3/'&(~ s"17iWk῔u2/F" 7(BO+ޒ@g5a֤>No)AEm6lKBρa? @?V9+-d$& V&ҥ1ᕃwdWknFtL-`G80љR孍n숩ϛ?]\uT%\_39_WO- yT4~AfGq󉄹C{EeWmH>EFڬ CGu2wy@6smjH4cf|.V(0b9 PI' Ϳm?ul:< W.jmDS`ñW9Sn4D}FʕE'2w$7̭_mnk;RFUa__Μ 0pC3Β<+wr\[HxJ- ʲtA틊=,787j ӭ"XavR`;wl + I5uqMUa$ʹb+^[+zpVrc\0l*+0!\ g{W^xr1^̘ B3w;Jf̌l[f|SuFaq? 01֧D?i!:*L֢D!Og`N7S*A.+)'{5Ta\Xl"cCnG^{uV D@8o u!tۏ;~n*;hef3UrF1g}0tb+lwUB+}#"v$}$`K$|urPI:t'AA^\&N-J6 S`z!n 6tܹ> Y[15"': =S@C{ɇucP?k#- AqZ&*kj`ք~H!3/?\ʨ/jN6j xE(Znh6w u$vt)hgi^(h]K%.3W5瞆Tz[ h]3^Z)ЎR2I !ZK.:OLӑJj>&/m2 MAb]u%}*sܔ"VъWXR{}ED>ULJjsHL#s׹hIݺ$Livyy,b˶7A_{4Qj3)Z7mhu&߻=%C=pRg:_~g KN“|*KgtB5!ј$+Ym?čr &Ym5 p~Z1s)vRWlZ֨F-?=w} 6B!S5s-j9 Mc{}udnC˗7Fr_Ke}*=WEXcˀױ0*NUj)o%WBݩø R)sSZsrvqLe'NQR"ج?dܸ_HW;~x),d"Cy(IQ31eCv_J,5 ! _lj `fk \ݤ:tX%IG @uU;}L/зZW]EKs¹}z>?@%tgE3**%7h~DvAFazNL7ڀat%`ss)[8ѠECR Tڳ. e%O1Z J`95cϻڇz9T~Atvh)Aۄrh!a9a$TCg6Tu]@Le9ޜ}DUqSƳL#Z<{ YrDsST<’@*mŷ ː%*Q%/;OFS>dlbNɍz,<_bnMfFʟ3ͲeBYxY9j59k 7Zv!}t"V_ 5{31:5YDD\F;[ v(X yDq]Ղo>j."Z>s@WDWL e8-"Z,:^ ుE.s.A_zu Qhs.<ܞ)蛹C(p;__ݯyd`U=ô߈?u: U,??177,<'O+fL89QCn.%Uimjf3U$KcHݛ#`2mu%̥gm3;& oXb{'3,$x={i]$v͵f1ur.ڊ}pV9jZ8] y;r*܂#q/7KI~B0 !e8j5pIHŗ.ۘ>(>^K_İ,ɮMNix&LAUL\(~~yHU9DI9w2`#Ao?8>&.2{ȅ SG2~> (} t8zUjE "*ʎkeFpgJNluI-/4a6uzvHMJ*>6 3WiwOylr# VLOu 91rl?xŒ5_ ̙w1*L#>w8z +W-uL;a܋ F!=y>tQ,P_bJ"\tڬ4b#8)LVdj_9Q{}i%/32S6k>֟Zg$)?~5VI)^(3uG6  s> ?3U&ƾAQǤcZ^>+ Q n@Da3',o_Be{/ λ Lk=/{7$-|k`V㷸 c1'k|k#}g|Kg*s,R9ndS4y,4Ca;mgZ(q, a ev7_lOiU=wЇ< (5ڰ"DJ{)?nԯy4*"i*jO'/.0d?gr#x{XC+m@SX+Mړ WlG1$8 q qV־јG)j;:a͆;7)TŶce3gQE Ddۦ2 S6z!O "ƇZ;uJFnU:#H$!)zϾ_w0o\1Q2$YFi֑Ył2f3qϾZ26f 5<J-2x#̜.AiXid71\tg@ٳ7dxߪ;=a,oAr(szb ,'DUN}W۶ 7%sbF?J ;twئݹ(*7fY2mۓ¢T5# i[Iϳ 3OIx@t=oo^L'AV_:/\6i Xlj*Ǿ hJ`ه '"8AHiqq(6S`S.ް)ہw$QA {/5uh`\'0~5)1_ӻj&6{Mf`Dbqueo/][yԼo<է[FI. wei$qIs젺-|%Naa,.$ȅ]0-{D2*wG[L5K\O :Ӝ"B| hB%ND'Шl(-C1Hk֖ޥMp 8ӓ3rT5C듃 Gm &)Ԏ6E>:Ţ( GD - (=&7L+u4U8-3mp2 )ѐi̐ѐ@ l ZuFGzFeIgG 9oyߒwp/Dh3N侣c0Eݜ7)EWz _!&}c{2CI41Mq!t xɚ4Cz ,"#UG-󑿝 Dj.sJ1yIԭႹ${i0Ey?ErKœ;ilpm>-yѕD vcvӟJ`yQT$76Qy!|yC(H1 Ce3Zזkc$(#. 1Fq/ƤƗՎ.6|q BLJ."3=׀@xaZbU?χ 0Yy&oQ.dqzB`YЩ\  ])֑_f~3gJD\ U+wٽm#VM%D_%)qF~y Pd̿ȵ^~¦ BU*du;ux@>zEr ar6XU;UiYUPK6xx6*sW%lZsG^߅y J䷓H-6+bCm0z#ث$v$Vߪ գv Xл^db;%O J4`n3=ȧ7!̟6)|p!Gտ0ɝI΂CEc0@7y%=]9c1͂%1xl2$)k  _3v-{+йO&/zơ (\< e?"wp!}xl4o}&XaM^/oL0KI4sЏFR1/ܙ,U?C :cKkl%ƻSoP^n>°cv[KȚIs4VóZv8`Rʫ1ZC Ņ(Y9Q܊j3B=Jovjl|Xig3\`k1sMv#MO[꛽<4E0}$ PwJͦ~#[vdqx`";&y ON͗!ȕ/„s'. onZ Tޮ(¶+nLB;Sh.-+}WVPKc[}yhvQH.A&PDlD.!BO7}R H;z pfYMg[fDu;O}{6e |mBM#,1?3.0f sY_W$DO 4Zb$e[ooW(2Fµ~`K'gq6$NnAj90DwHM8ݲrT.21 ^3 S92';5MZ>Kt|{5Ki³CNJj!d4Z”a{Nm,꛹0j,|*aZ_T pRmp52t3#JU5}9nxMZ&'$gopmUnvJDQKyg2bv~S?rS@ k>v&h6m4QۧBZ!?5 Lg~9``I.er%4cAcS8iOXq`pvAWD ĴXbTeS e (ACCK زq{ +A{vVaLWc;K 䝈hdlc"GRiG!=*;&O|(H ^$ wkXϜCB0ݪf}1$fpE [Jw7Ձ&b''Cf0yVd鍚Þ\wiK56WW|^'w^Dx,%VC'3ϼEbbwg|aҒ<߱YA]yk;fm{G55PRf a"m_a_!DqxR.臃k9oIB_٣{C]}ڐ$nPjZM+{]Bzњ2TĿ8853 լ( xCZ܆HX G-Ĭ`wz'09<ɋ@SYe )g(3kJw푞 fce+9Ɇ$_$F=Yd{L^ү}g%k-nяm)D.?!}0 T!φ3nO\Cּ iv,sk'P9_ka @ɂł\x@}|5˼xji \kr~/dMF*PmX_h{A,ϋeYFiP@c5l|ҰԵ!rP?pj~K>pC]-ؔ,◒po3i] +Nл~Z(4ȇ 1s=/Zҥ(7#%۾!IIag3 5^>>kb zg<Þx~Sll uhy&4wJ:Ɋ7;#4wREi-5Ϗ> >1RiݱUR({Qz/IQlӠy2MJKd &lbY2aW( J)λgI5}KSF9ze1^cw#ck #D#E)=fV vdSSɵqY4p G|mPUēhL6g:C5q/F ʡ G1 UY-!sX&~e!B_R)P]&N1bkѵ7"l6+FGAOFȾ߾HF)OuzwS;~eyT{L~[sz~¾} ûtğjAٮ ] C'H 6J3U| sgi'V:ĺL+~>=ziږ'43CmJ3IдRx_#nIǬNZh!Vd+_@JK 0fm_ A8$rKK= Y5IFWL3<~]oH!['o5mO&qyt*J\8@PH&SKYQzN&ƕV<9|1 O䂲[L'ü'CjE%qK*1 ) g H(Aбʘ9:ek,{Q(Z(ȜlP^B,b[}cNO{f 搾G^ԙ[,WZ:#^/'.;Mb;r=3I-RTj8 d f=nvLGk++,&u8 R{M+(ٌy OЙeRY*70}=s '8: eUe> KW1nA(3jaŚw`xrKUXעi ٫\j!%Dæ{m0v )izeL*w(P5 4 te)oC<#Wv{v@76O͕bQ-~r/%BѓnFO sxlۨeDO8!ǁ,\IÃq˻P'&ދO9mg';.7:A_}R|FY+lۅ/2x٫&AK_kx9=ZJ><eoWcQwv?QIlC'j4Z19 !$Ng@evj`[r v +izB[ŧg_9i$} LI:'S@P9lm4a2'Kxk!f,4T'Eߐ=^Lѡ&0 -O/F96rN~ME&#|+۾*06׶w401MxY+Mx+LT .:l33!WgA~E&I YI)DMꓐ_FvIERybk9SjCWŸ,d}ԧntWL)[!a̋ s|& YX(QQ~bD\jU`۝$ɯz iBy  Ξ`|"u Ody>g<'xfTs{ =hz=7֧2ꎷ\5)2Я]/i4UoڿDF}>e=m.@ɽ. IPKh'F/;J =Ky~PZĠlqTT{2(7SXidܸxpJbHw=m6籔4 %Q[= .^K[>hQKVOMu(he;+t!hrv{1n݋])]sˣJ&dzK]VUq"`KZތ7Tr Rmwp\KS ?X1M!v1==>} ŒAYǒYQTfE j?V~ ,vb 65`NH/ ?Z:2&=R7[YI('!0:5G+KFz_^ [g¸.iVk%uqpU=W0 0Ӧ ^9֥;Dmެ1G# Pmٜo֥ )N(?{2GZⰡӡ2sgNϕt1 ~$T=oPreaUU8[#/\ e^ Փ_ )/Pk!vKUϠIMx$TG^4F,B@dޜM+TXSQcei('S]шu,09Eb}f8"+k:"\n,O>߳Eq>JW逜sR*أk68JVp41\ڒ XV4_Kddr٧`C#rVŨH-`*a=ɱn.Bk#ஷ;D '0@hs&1ۗ-kh/2RϾ9'G[EgCK2\™0z{gǛQ(!t(캀erV 3\Kew_ iDm |->l=(QO~` u4*8U;:@Gǘv$Z,]qpx \|O/lVS6)4%xIEph:aH37Vȫ5l!vfz )\?ή@LbWϙ[K,Շ,Ur}ۣPr#qBٶkd;OQ*+,\AƼ`i[q5= H"F^a֐=>MRimx39frtv{y487_(wٺᠪ ^]DsFPs|t55y%I^˸".اi3(\t3&ґI"ǪS8;rc,~TQ}穟ecE3+p>`X3f<2C5Fi Xmj%V\eLqorMKU3ZApK78;bhAV+y$)> :̡67}Ϗڣ Q3`Z_bGd` &@S(xJ%9Y;4jk <.(W 8 3ֈS2zb .z̺a1,8͈#DI@p*Ǟw/*R 4 n4d6}cV9iA$ ޳_ *5LS"W]ty*$hE̕Ae+E~=28[U DN!沅ZK;kWͶ~yov'b^ >B /ͮ$ofc+=ز48h\q$NwuPͬg4[ُ0T,jMyS2rF\hgXE+H8ִ(;j?8~kR6K.4#8_Gb$`#C]FR-C+h#ɤk~p{6fL`g $1>8xyb}QzQj)EiLmmÿE1S3' (=㣇 0I }s.$6D󤁤Kf)!2'mPe4 o(6=7Y y\YI.zz|_ 4 쿇3I( I*fŮIUïv%ٿԦb@Jqo{ג)5., )_b ¼e}=;yN?V+@eMU]wFK%;3P;[4Ā\t_ulsNt4MYvܭiEP&GUMa\HP 6Kߤu ROrm\i57&sA5_t* = z[< okB,.r%}=/Xlt1ЬCH@]}CIo =" s}3B>%>k6M~ᮮcN*XEwNy[$H65[5*wF6BJ?Y~ԔA6A  N׼<g0h;UP'oS+S+.PuoChJ  @,&TI`Nn{y({sa})@9~;y '#z:yyny$aES)y N}ɹ6X=9v&WhґoMwowyT7W)^5ھSt郆y#$hJbA}NvZw-j' ӳ#UDJO*zV0j`z]ZЇ/Fv+4 2(ī(9uCdj0'h%0V 3<5 Y,\}ݝJOoRUh80yPGqF݋ ;q䌅\#V<C '"=p_Ǥ/U>O̮2c0XDS7e;•Pc?gڝM`1A<8['ʈN]G rAɝQܤ^;|dC g2[[%[A=~5=BzaBx{Y}gtڍ1J5ӠV$0? vB6g_ݾ.cHAKGq@,Ma=v*TE ga)PPXY*SFf$B )2mW(F(T,wh|=ABÜL0mȤ~Qde gX6.&, CPH옼E<|['ccqzi:K+r|ck˩(KӃX/ |GeQ*WZ{ c嗊UD[ A*p%?l=Tf&f &QbxOܓnN++0'|.,<*!4mb_GYW' îzF#2 ?A܏ sc`|K,v=u9Hd>@'gVtOPr)_g zIج!LIz$6*r/|\-4zL <?-Ȓ5,pMű)ft,T4Do#T`:y'9+0O8Uc% м]'׷ӍN(7$# &Jʒ$$dۚNH| wIQA.T3+s>1Ggq߽*HjEޚm1 ;E|i Y>A=p-IT1 N *:70X6/z  7?8ʷCe;uAg6(q輵$qz^[0J''XsL_zFQ@nE~˸*淹0 &į%o"`% 4>%)zhN1K(I$볗s0r/횛kSi|3Bx4CzP..Y0D, 2]N Oyɑ~x-k$J^j(k{2AʖYLUU@a}}2})D5#"|H.,:M^ N4&^l6#`N]X6s8R8`oHhЅ:eۆً3ІΖkK= !x7Gf^8eCHwRC8|aiKO)V֞͐GV(өg.&3ґa-JRD-$`=m Ql&L4޳&W԰EDByMs\f+㫭m=ڢNdAdD=6ׄghU٨*͂!EؿLc}h[QE邺"Zq% ܻRⅭyZVHek4:R _MRVoX;G+[V+SLޕ7͆h8s/9f~e~Aq6Y9`-djɮLi,a %-3s!}Cu?+J(l:;,.ww6ĔbS/60j;d]j—j6߅I!?v?F7b._h~/'Ɉz"L֓/Twy75d:\G:Nm^=*snӟoe@@D9{C< U>}L&IR N˙[%ЮF0 W423XjKsg H&pCNvX88*lI$UhKx[ÆE%(7PE:1TBjE{cӬ¢}F9iCbf*$M͇`+>TCV!*l8`GB!}qDOnAӄCSg?oW8`٣Lb>d@4NnE$m: xF*8֝%!J"ITDXxSta$kZ:_z6S =K(낊Fq\ĂH\ixYVjި+W1_w\G nlA9]de爒{/J&S +nWԩ k59Myv"9It`T5ڌXN ^q\O=BFK׍ݓNz+ ?)A=錆>%kV3H;ޯV˳fL 5X((4w}n.iz}@35 ܛ!F|6[M5"g՗1W#UgѫZc-nV``f2> 56X_Ƕ,^ɃW%,@Je4.+9>#l\,-+v⊙W_QZ(yGr~bR`;RwO7m N.>(cvw!3E1p~q]Ps' Pa/Tӝ~PeVM~uPT0']-?&tH8kmN-tvOdn+r=lzL)1,LP?=D4FKW( ! CetVě2YK ַčkf֠3~uĈx_Ntb&7I&="{fo绢5G4/k |F.Q\KtYcV 2I)h0%q+e\&;ؿ{tq-[I1x 0۰1Zs F95 7OeD |.-S-ܜ5zDn%COdƿd^/ZRSCN%֬eȼ ݾedaƱE)[+0Ue'ic %&A''e+lޘuy ATyP+R+N]EY12ͽ 7 X?F&]ѣRdS[(ɹz lS|Z 5e@EJ "G9Oaܘdx'9_L&p=c=l8H/(G*sF);KݼX._ŸH&tY+rj@AaKhL(iz6rOy`_/NLv|;l6nMZU]m)^*=HEWk#Hw { x= $?Hγ'D8Cwt8a^`,&m(Z04 2%]UxNaj9emź4 .qtxE7F}B26~yS˗bH:hC^*a? 3H,97'(9/atN'oO k 5Zx/ΥN(d:O.~F G{.TkaM8iD #4 p|r&UȳIUEo%qt]EǑ-hXݤ0{w!BviFLܐD%[)fn+'lZQsʹCd$nPoʚj4fG jBI#fQӋᄡTO_yU \8;!So1Qy{F2aI:HoXCY@(=52%<37=, \nYtNd1Q]ԷM'*6k1I-Ӓ!EwNѦǘy53IX7Ee|Y4`e' |-wTXˁ#:'Ńx/rWhy!Iʴ精s<NբG}YuTov |xqI$PI-KB48cx9x-Qm$tylI_&h0wf{dU!4˧55]!x;ziax{*.8:|R#?ODr+ p*%$1ZC g}k_tRIԦϖqmszJbq @IԊYBi[L\q)E'@d ƺuUdޑڎǻw { /#L\Y^*5p>Yރ.< C16v 6h"'&==4g/LBRQk8^*to1_ ,})zcO)ғ`(ָ@H˰шw 3U8oîd]s wbLA"JMd>B9w%.be*8˽__4lJ1-H/JdFI9(ahk, p#!WB푣s*[!~Dmt+M*;pmtCX]v MH(}yKcLJs"<@&pf]E+aHI4a\>Ts7'EDʻ%+BP0]҄ Y;Njի_0}7=k{EKN:v%x;EP_(%FLPD씃O`"p JEA2uF,h"c yH!""`7Pd|G+6)+j-uCXC [7'&P&f+6*ntmEB.%BHВŚ0K'>1G i?`#}\jHD!:ZoxOJ}c 431懤I~ҫ~{O(VUE P",.X' %aR7hTɆ-F›z9Ѡ`(K+ 4u=OˁpX&c5xoķ (ŋ(B&2B[HR'Wu,A +06lCKё]֍lBTsM6l:>H-R!"jSͽLS2Cu?hs  z~&^cf9UH?QR9%kkbgQVlRdٓ.U`p{]CDǼh$W7GXpu2,]gLvLC?K TY?Yib")iŽJŽ5RnF}ϫPr*1L'"7A}ϜZu.T2W8 (bY,Q'l ~x%8۳:Z+V飈l.@? p `E[![MLٮU]U\C9)TD撑ݛ8E>q^r0e-j}2?y+uYdﰌ V0Ѳ @=j Ufo_Op˿9Zgkv1K ROxݶx07֩W*'0k؏ы;\+DJI1qw UB~&dec>rF&"&-팳i8J`vCf{fZjx{B7&:cNj<ڠm6֠JA d J<4UXRpb~<SRYҽ+84w$FA̻fTzmClntS~Xe"|%3DA5u=+gd )6׮t\#,AwT#IGؼ[VczR"&v T.1k0?epORj_gھ:ct웫M}M =U9 ̰3U |): n= m/˨(WS##SJJyM "dtMO|"jީ3*dyϒ92 sc %6K/A3y$;0 D* ir}~qsdấZ?_È:`× Rkup8i_Aˎ멋E}y!GuԲ X>hAؚt kTwJ>0zs=:Ψ[>4LQ >~ ɼ=䞄^,\.A3"F?{;%ʉQt:0˚P{4CC:YpC[p2V^W*$QtUy x$R^٣Nń2`x j7?(}+EZ}(t`TKM]xԘyь.Q19C]YA,MSұCkRIF'k-Qf`L >e9D2vU"H)՚]^Ĉx2 x-}.I>2fhŽ!ܧm/YCJ|etJ-Vd-30Ŗ6#c7jrkۧxpE:rP\Ƅf\#88 cd6yaI`)bdy9}K6cTƱ-"4`qbhߟ |"UG kсɀ[V(C>׏w7>]f;̑=G>[rԧml[u={ J^ci,,&Le9*S=oxpT0- wD\?Y'<0 :qT`RYBI/DGV'+13 N< `!_51³Wo:}#`qXƕN&K7'!>P $:g$[ $AIj65 </(*c%_I=% ݟ>svl!sOi'muCH$ =ڟڻ@ه2$D.2xB 덲|B 榕8v~d,eo4Ϟ~W]k"s`l: {$^nLq`Vw.A~5m߄| RUO(J WvIQX~Ko`;XɀULYF* į6bF?Y v-PdyǫZ1a&pDJ:c-,^oA/HJD|o7鐰_"Ҕ*>VFTJ*ަ0wf)&G~4^m 0^Dzɟsz\dJL%.&_Yͅ>VV jU7\dVEgC[(Tdz Eb>c^jh6/uȈUy:ҵYcUˬѫ(.-UH-|&Y;01(L@N&q+RQy`lóLγpR-fe}b5/EvS*!NJaW0wOhKPk':"Q 5Qcپ˖y-cp 5,.| 0aWl{ֱ}JL&#Q, Yvuv/niwxoqBB`% GwR FlJqᾉ=@!oC^G-|dR-m1-E|!N[^|~[> NJu&YQ|Dszc S:xEpyQ? UJaI̮4{(9◆/h]rxbߊdoqdWD}7~ -1;3†֭oj9D #K0(7/GJ>V|{U1-;<"EuumNB\yk#5q̽I#C Gt-t4ݵd1+&nK29ObFyiVζc\|JvzJ9,$*%T2J*8x+ ؐ72,lo Uu$ ?IE*pVcvk0áinTh5݂I hӽ`0En~ۈ_t\bវy+yKnB(>/*S=r`1c 1@pҧItuJ {CCDyA}hm Ɗ9fdR.@\[ nKAM)_ >ԛߴs(/Jq+:b k&MQ(mp޸tUmzM2/NʧQ*y6X޴cZ0k:}\yp 9^V؆ʄhv?nؔ9n l9<3maL{3IC[VPoȺU1;%Pp#p2C(I<(VO^l: Q.k3_v͡d灔s0CzA{TZpA4#WV Ro&%/}ԮpT9ΧZJFsetD ~ $zϝLtϋW%ͪ0#i vs'#Y^dKB"d&\ʐ0Ŝ4x xc;Y)9^֓8}+bYptG-9۝A7Ӑo&2H~{ow7>|rkgp2/F@Bnݸӻ2R@0iMQ0 Nϰz~Ph:V-<.4I u_*WRRq:u gxnMp V<͇엥N;CGg?ҤvwQڬm0؟q<%+>VAJ-oXT~1##c~'fild[saUu͵Un!K~?%3z=Php2㲍adfcU8]C b ,FW!01c$1(:ӳ $wPKV,y/cJb@C>sM)OF3MA:G҇Fx)ŲN95*(6Hꗄ=Ef&of)2vʪ`q33&6x2"ʼn@?P.]πA ,0% x#hST)eoiXXh=Ccxx|=٧NwbH3Zx]A@7Ofz˯(̚`p`L/u#G<ѯ[A&4n8m,¿k18ADa3TqN? kȒR36'vxzI _>k&^ZZ b5iz2 YZQf,N2E]u8r*0IqH9)PRepޣYt5.cr$&+t3RN=pa M1SRơ FO4kAi'cN;UTr|ˎT1y2U#1sI3aӵ"m[7;|a P|*PCʌ<ϽJ5CYҒjΫwS;KߏQ2}5%\ɱE[bǨؾvA㏙_yy 1{V?p\3aS,ae@O f`+.Q9y#:;c\ު&ND4="w< .^)q"NV9QWqMnh&(P"78B"C¿A뇈84pMŴ]W*| iSp,ȷ2],}`SZ<@yxb[{ivYj wOH<.a"LL\'65l;o ,*5t粦ti/s?+',9wCex} C$P,F%Aٝ)52X}23eqN$udPC9wCOiFq|"Er[uɏfغA]2+ߵp|r\iJogNX0;hܟ/tj)F#J>i;CfJeNB|w[+ /:Ff^D%VkeŠpdKڗ͋-{'a3?O,_,s)2:eV/Maf^);y:fv"̒'SAÞV kWG+nA/L)pRGPl.DL*#xob@׿Z{iMޛmuԮζHr ^{|u YZ+(N}Ctxinpr ˣB$73օdZUxC*K-Y~)uO `.so Va֘xXIR Ñ9Bv`ɚүa[[yZ :+q#SR *Az%[f`}ky7VN(+Yd`7ɋn ޲Sɮ]lZewo!h+G }ya їwP9jm s8d;]ߦ-x|gېaq}x9ҀT~<ܥ2-R7'a؄6E]jRNj,W"<5[>.2"B<  K w1`ZWٌ>Hƫc}$IMgF0%K4].b C.XBVͩ{^ls?q/Tbzጬ]ZH@d:;/@ێR6[op,;.RcJ3"v+f#6cK&2.v-N EW_$M6"|sl@e-c\v]vK2T64Uo*'<2̹q(;Y#&r0>/$QOne\Cj+Q8 _ J`+ۓRubx1D9YQ{ߜ􌩯z;gO5R7>Lv؍KpCoųV##_U˨Adrw:kzڰRwRf?%88RձByl WNpLAOF + 8f0*d4d&v]. |7ǓoG7fUi yÊ,°q$UL^)i@ sM{A+!;nY~F ۣ+~_n`ϒi{KnY?\+,m6Mn| 5{ qt`extF61`RL$mW篝f(<=,!*l6DKɴG-]Gg+¿]%anx }='FIJ[t ީ'^5Q/<}?q~K E$/D'%Rǥ^5SV[S @^j<k>1 V@UO0Ly'eA/@M\ ƞpt`fУ {{E)mrp S%ΑL?h)à %C`IuyJmb]nnKz>jdmB}:&ySg1[?8aaK<=#C;[an.DCjjhP9O/ǯ^Z 8#s Ei UNu,әyc@T!h{)+ryI~0(C|5B3䵚ƩoU!&$Ѵ4khp\=tXdS #«{ݡa_PO0ct=Gŗ{uQi{aK.[vejiPc%_u^zF0? Lk岵lYqv |O`ʮ\[GM#^mqD'ƻ2XI >~@'hM6ӭz36ڋbJ\Vy?=]ݤ+/Irmc6:NWa' If?*WsjZlBWYdD 5I'j-B["݉"qEgMydiyELΪ[Wd?wU B>Jȿ3 #O7 W *ko!]#cXe]9sj 2U6JkYSBY'$ D{MH%ב{2睱ه7ljRWMq[EX!g"亐ײN(s?;. 7K>g2l #,LwW'q8L!(Rn.׾3qfֲ(.~ckN[8,Tucӻg'VDNU^J#*5o<ؤ'as2v0Zί `Ѽh~! Tn9ܶ(`i\ۙ@a暢E #;)^!jS N ,1Dh<י)nO os4aj|}pz [8xh; ] Z#nW٩)KNTMv%Ľjdl-꤀2o/$_-z VYI4S?q1k&;j]ݣf({RMa#֖kf 3@யt?b?ĪV3;2N ǴbM[.3r⾗ \sVy8*ȝge0MZt}`kp,;_y?S>?]<b~m2kh{i ;\ޭWjwm!βZp )I8oDb..> JfG`D.RsFٮM>.Q2}eS8l`OԷ l?=AҚ#afȀK$MfAk:Z}n4Orb}޺I~gA Pyz?F67uW\"\@v6|}|m{`j X %Fcugȫ3 TL}Bċh1 lh5KYBncW"%;8qq%@+ 9œ7}){ ]$42(捯+tEԱksW J&&d&&TH?X(BJ7N MimڱT ?Gی{,ge{wB$>mM#Q\,Py:nqQ%ԍ !yWz2q:QXڐ]l%ДGrοf0oGS#\Bʮȥ"#9L] fi tro~+p! 뵏 ;m'>$oLǟH :,m(ț=i@(W(q'b=+,&Ծi sTeNL-к_= 0! *V5Cmd'dtttc!&c]eV;Jƥsߡs!qpL^ wW~&MN]w(QeT*iҥ ofk׉OZ@OQ KR:V-Wug緇r^j}-1Q<)p%M/ h:D|6^@TStj@XyՀnzw2B_iV,d[ g3h 3Z89ґd҇/''n6WA ɻ=.`vAoZOHEzw8hp4]id8ۊDϝcn"kG=W'5b񪐼&k$ĺ/_.$,\ J(Xvl,U@NMl+%2G82ZQtI%pF tlKCŚ TF6}ft"FcMH3a 0AQ Avl[< A i<%JaC_?@G5zli6zHnV㥌Æ\BUPZuZo |PAҘ\T4Xܖ?vz^B@:gl1pø/?4OM_ܱ<VC"w!rlVd9hэoͶ st&׹'Ji}PNND hZsR[~}Vfa-)QL ]tmyX4;"M,;M).%gә~DȌ4>$g cjrFP"kɑ(>gUUP8\O*c ֻ[#J driP. et^ xŽW#!/sH ^f2*d#0m2AO}Tn&D`.Bwux ZwQ,U]՘+W.t'.}31 ӟbxy^S"[i:Ɇ6{7DJVTFD5S ݼ,N)&575F%e6d# aIZFf= Yb6Bn t9JÑtANcE'J˝G? Upɷo:1X!ņP (d~cA2>993 KGC0zVйAc詙fhPR] ,ׇNȗ (u:ݕ[+_>\M=fΪ̙atMOaG-<,o:1o?E3mH`Z39 @zPh2rX~L[[ee +KX,k .^u$\--k^S%K.ڮ* Fq4gɣR.nJ3d_ѓrtb ںs}MDI) a{ 3Ψ2 ndm>S}Pxlk$MXRsqDūFxo+ *hMK'*Yo;MZI%Ԟh*dt'Dy̯4 50*Nu0;NxzQ\/OWcٻJvnVP!65NH!Z\ghT QN+~orI4X E1k"Va Cpuz ͠Gm"CZX}  j&Kd."-қlf@[xi8#@I'E{uP܊T8AyYEIJCc F-L7/y`ȄwnT_@:5/\ VVn͑&mB˴'w ~=<Ƃaῃb`ű=l| !9b ֻC@ư8݂dJ6эAwih^%3A+)Vxu8'CTMq!O鞏S'rPOVE,3tt& 32;Лpnv|^"6acXWZ߷*aԐp3 >k !a_L>k|0(gEAX7ʮѢO &:(hB bTx@8!M.`r?IwՕВFii$; cH_SF4l ˈY&D9 =kcTÿÏAT`7m.B[JB^~.ke@ ,4JkHb]-dyzMXۋAVj7~}V@Z+ +yLI)6HP+SX2hT;p4nM}?\-j:a-E@S) } \(kJ{oNt'|MIb>t$FƵt?AJoj1*tJf=teeDEW&BW mwx`zʄ^UDHc~m3؉~2FgVP7^ž)S+',kȌ=V6ƥw!ZEυcr-q&{Y:pZm )ZltKz[@f+hb(d_cw!R"켾c<򏢳řhVTu61 +y(^ALrBS ;EY\,\ _p\o',3,* ?}}_|zweMDuN'^]4z-d4?ƶ4d yqbjX $T ym#8#gNپH~foh\쑖3*\;vlK$/Q5VNt6.Q>?*X7ŋCP{,嗺zq’+>_1 @캬#HcS k̓XPO70?>)9p:dlyj`?hUmgg䈪icIj޶hFD}x!O5B4SAH|Guʪ̶WIT2Y (^&da^ZKzvXX ԇC6,|V-{/vVWBj́hhY&XOR堋#l}gmO|b+TCz“OYL*gW_k̃xǡS>ctT%y8E#%Lr$`ɂ)/,201\:n'||>NF˼Z3rTG)5hH(x3wN ne \ƟANH؀%2 m]Gi::2lzYwB^!p?BwCh_Pz. fSuKnh 9Y#ۜ2htx1d=ٿ>`%c=>۬˶fۀ28l͐fی|,˂eng=WPxb4*J]tb/W Tb__.xWb` §`hپ/ӕ{\-NGFfr&~R~R9¾,#w-nn=OgX5V>r?ښ+yvd7_+K0/Q=yIv`.h"C|ha-NW28psRyT/b <`Ӣ{!PE9C/ 3 VPk1,PI 3h0+b P#el>T֍RY1U\ LD*Ϧ:F9ꮲ C V2.70t.䎿I{'Z z1LmyvtǞ*EXʖ+8t`['kx rWf%Ws}GNp;fh`IrS,?.Q)Ñ;o^[hp-W25ԃqY3f6JgRy}Ev؇>8Pyq\i#Eǀ$XctC[$ոJ(l&y:\Ln%}F^# _ Ag ^D8K X(i5 - hbNY&Mb;3/.'":oah\ >ܢP1p4gY IVR$<& Xοkf w7iIgӀ+"+@`2h/:4uJU@.с>ymnyԏ4݀lKhR-( K3ޭq]GՉh*lUz˸OQ m%1&È(sFe^YC/ueViݴ*?%H 2V%kOv!LHD2ZvWl4ʐzI;1~f@n\orWHHOI+vwOMd+Jp@ c%r !Vmӗ-U<$RIdX{T#]"ٛuȤ'/:AƈMK}RqrةfsDqN[ѕe4׍.ESPwrtn^pijpXZT(Ya.;CAmPՋH`j5 {,(1!׻WQ@ \'#@UNwY:Xe9c4%s(7YK6?YJ,|>}#W0ӤG 6qQA i:Du37kB`}zuǫfxj Gxr 1 @ًND/%{NNӈ-1VA|5QEw&ȣ!p\t (A ږpE WI*7_vW2yjIud"out_ma{hp;_5}A3]zд؇ܨV6Մ Σ =t]92gx9))[Iat*沗Y]"|KvVxvh{*]|I }׬Ap/5HNxU9~x;0ot6gnP^}F9%@Xb>ڜs[4b\3BlU/qm )&R,QgGH$LzгPc^bd*yS!1KMTZcҧ"l;/3@5x ?d1E^hK8!J6X? p| [31b;[m4 ,i @Ez C1/$H)HѨroϴ# G)TPٗ+up訫in4Ơb>pa&oU$dYp i >zC^;Py [6% -{zF 9QA!PP@pw 7͒ӯ6]әYVHkL'A׬M#}`PA83M5N""ܲ!VX[]UGc>gV g垿$pv"^gfQU7xzdqR5`jVo3gsO`se31;ڜ=yY@ԋ< Y>tf|t,)@5vjZޛ*0O]m~3|~ 1%pW⹱@Hs;_gD="jR;0k!f5:"pa`⤋]NZwԩyǁ"w^L^E J62!kf6Qa$gsy@[RZ8H(DBff.5b=~ۢG]N /*n/.`ItC}n{kË$Fn*VLDP*5ڥf]Ҥ@UIelKodnNwy<,PNDy|}W',-x _ G 3{=Q\1;mP.`G"з{)jB7t Br|lBJѓewC9E9M&!O*zKl3.2lB λ&N/МmBAu=TuqcTxQCuO*_e#z9(; mukx2N@Iw;s\t=Z|L SPcW%a"hO# n!Da~x~&/!@|-K+S_ _ TnхTss} ش?:LyLV(!<vh ړ`ԨȂٵ #KCۖ2Ҥ>3JS 9 ;KC-?vSȋmam<0׫#l8|>CBch ~e}P,%moieHXͤ"it[s U Gz &")"Ȓ[CgDV\ҩ[a@E̵h ?hcZ]Fxg_A&=KIl s%]GKAh#$MFtdmCǞ.9aeA#ߙt߷,G#9}0[pyjt k>LnQ V2\VJ4#(sl@zi7%̋ G;d 0[ZFX7#E۸&]УnlP?8qTW*3Me'0%hFzo~ 2vHVzrL.cgMD?Dr9LA?,m[}5yP7Z+ZEEJY^gs®waٵ)~Lƅ6ag9(p:xgZ ]Xw3S )qL7"_-+hr{x)_Y~I_-t0۩I:#к4{`cO?A!hPUW$|6^Prd<.£2$Svd́JJb0Ӗ++9&H 'I,HQ;K+iWC@ TMnc'`L[kK àLam(j5f_%$kꂷ |.4SyDK0-G1„acB$>x1Bj1?nW&/sUcx+P]^:N0_8=3do:aPP&"zE\IiQͽ$@dY'}f:Ϸ?ՄlWucfuZ?y+[7.,P5kG+Pd˷:%K/3y##@}m#_-mm:WAx(Uzk}h%`%Fq({CLyD`!`YR([*CK3gw1Wi Vkq) ꛁwE{\C.nv;v 4bZeW^˾jd'N Z$rSoVNU,ES  6dq2nzv J59(D$uF`qS +YhNM  ˒UxWWy IBh>eTA}MǮLǖ}{!6 MD񶪁Ǖ=͌~Z)u=+%)o/)8]nUFd^{{A^<Ǧ&xQP+.f]V'i ;jߘ@}P_)O?϶4ڕ?LHڢvlpcZKiE\`o1:.TCEo)ܽɵɎeⱪ\)I誏cY2&\6͖~L"6I<[ bL*O&2Hg]9!d!ط䐈j%GHWH$B< JpZ|T3ki2ڈpQ$H@,%Zΐ e,XeW/i*7Uic,t7bŘT?J?Y&>GKg:蒝 PB~24ڷ-`@h5:@\aF"fS ]B~H>*uVpOpHxc흱qEaW%blgf`B?S-_2EK:* ,?t2:nP:Tn"$0ݜJMUNxܨ%n:CU3Uf?Ql,sy.52N7w;wA IIӭlI] F/ɝǗ)Kr(П78QIb.Y:ɺԙ`Tkj3xNzjrxv(S.Kܹ Q [xwvdԨHks+~OO~Irbo!]N ׯtFȵ}/UaO~ Z.j {փ/2Tz6fsbJ3:N(&<1->8*|5U̬Vޢ[{c.d=024'VyunaݗT.wY= v%imm [Ճ0o70h"WTޤ5н" su?^f4Pɨms{kD2|!\eEgxGS^>u[ۚPw274Ϫ}=g>?+W|nv)n<.'A2!b"b8r唃 N,qԔH-z<{dgH׃ϵS#c4q [wk?Vߺr?bFzQ'|{ON;$T(ر4p4#MrNޡ4XH.WPM,z%<g)1ec0 ŁȟD'`Ox/&yE;e'26><.6(zvJ Š>/@,c/0} ueiLu M;f,}~<ˆҏ$ba=Ps y vG-uQ+#Kݿ25WPX0Bx @>{8Uw7Ikr1װ\Q36MIU3UM<Uƫn (EΕH%QUHR4{sjqqh5Ȥp mkM:ݳ]ZMA!gX8/Q{WMRk//C/߮ZIqvD3fp"Sgם'fk~NA"* HUh%xd45]Q9CĶ83q2SSxJ e6CW,&#V}!:MNexvԼuLQ}̼DpI zWUM@?kU#}.lї?Fg͗s8VȪӽz4U_7c2i^~~CCs8?B:^.o|vGqG4 kgKTJ VG1~qRQP&#-j+jGЀ|KuX$h,WL9Za-gTsqVݪ)GY̽&$i3qdȱ#l%,qU̯s$^KGS)=Ďp [hs`˲qrhp&#ew#K=Ia.: \/yR9iv1_ՈBEO:@\1*v[`+f(%\_..< S,/A}M(aBi=R5'coJֲGǕ*_thǹƂl hA؟GWZ^# lq"U{|&x^Ve)(ZO/YxqO/vbJt+k*?PԡlR%b̋N.[km2ZWn'~~S))@·?#gGt[H稈MaNY8Y 抎f[5lz<4f pbI6wpaqR28t'6A ҁ&Yu_ݚ9n&OA);Z5i[$3ËKFTtbn*,͜j n($]w׾_)iE9FAdz1r98&n\gH I1":jQR1 DiRKALr1&^gZgCDV'%?iw'AWinm~9%ƮhLL !(.c^yr4 &CG)+$ˆlƺߌ&_Qg$$e -ԁ:kl*"Z; &N='; dU踙!0淵0;e% 2G*~/x]WA܌bBvEhq h0-3L5>JB :zOkTEv +wzcuzQ]g=![G掎AAI_|p]*F&&BcZS?_"8w1Щ!'<\R"a,1Z#B(1হƊKe|S &2)M>S،+5FUڡ>088hc$[o$AחJT-eYp+]fk/*ʭ4BLJ 7X2lc{ƆMZM!l\IlG Ò??7sL~E-ڋ4'|^MMǏh {[ڇoF7Rsz\BkDHO2NS rHT}~iu~O%Um ?7(&P҂Xm=y+joGډt, Rmgx)(e[ H5Ѥ1$k 2C-By0uit Ď_~mtcƪ('r$ɂtWMxB~JłrE1JfjeۊVTqIgga#QʹO(M݂ B(XJΥE!a3eݰ~o6w2aO2l@˝SRy9c\U.Hz fe+T y"Lm:Kf/}jjp`ƃѥ͏XK>@VV~ѫ K bal$21\)nXh'k{hA}ohNC 9)S +%?E|)$@𾃶D2eG+ ՎW*Gl 7VMg2l8_!7aNGާo;KpdöfXm,#FXV3)aZ%lb5IBXz*͠iF\ :gfj_*SB'LxyK-xdVzԀ:j!io(R#Ti#g'/JorR`pҙKB\{id,%Y=X PR=Kt+૶J7⦏ē`nl|gٺRP胨VV'eoJ8٨NMNSI)3#GƑ#&/V*tRib}30/Fd&Φ,I@w">1&Mju )ᕖv(ɬ()DZ48NW>d2rVpA:;YDyceup5㰸DodXY08P5=0(}QMHɢY`ƃG}X0C]R,̡ÖWS cRRd(FxDj[v3(a\o_Cc7pXsE` bnVf'd9VAP%fv@7I#υ4gdA4?B`F͒9%H~0ZMfGPm3_ =!E"Ёq?P-.d__Tf)P.dɺcm#'i,w0d$PuwU-$%6{Iv9ȚsTkRúo_BPy꿏 A:%,Le4@6Ib9*; >C;z%st15jY#&+v[lX6D>M,"=@5Ouu]p&O$Z.ď*l'{&àkaFhcrb>5dQ`` mڴ>U"T<Ǝ fC#-p͗e숸p!\^ &`(R`q* ӆʛ,R|Jx )xFXRQJzAhM*ƃEXR=|;FKPw$<õ%fRXPB=]5:%!Clx{wS&OynJ%*s1c=>;:/cksQz{^z{èfd1@WՀ8{C1et;zO@%FaK:)"U[7tLbQ'K<1jZx/!A۶7;N+ sЂ4>RJƛ*]">- AXf1٥f`o7B߆T:>#,vTܨʪ"`7gqRoSXl .m"=dH ,7l,"v9A?p2 ͒ިA'L s.5c,2W"sٚ:~$uX h6 x>;$m0Ylk6/[ ;av,.D Î>KQnN$r"خ9ߚ~$D! YkX W-,)<q4)~2`A-6[TBNQu * kpekݶ0ѶIz 7co7]odVvJu[M8V"rQW" Fjzq'[y~%pAU n=FW(~ F7uΫw,6YLG6`%?on=.Qp <يy2B'oEeH" /SWnTm"HkKk!PẆ #ZXFpx~x|A}"IDixKMW}^#(-Ek_#agE 61AR\߬VyKQ-MѫR+QjeiᕂЁ R !0.Eݝe o喓5? f.>hwmgh샗D %G柈P}ŌxL02TcućO1٪^$I?,w8\hc=L+&EU"LS-Yl۟w:ٰ}yZtH@zE奈ے9AAr_DQs )z+"T p3{ɱT'THïڒ d=7X%~?r6Z}ękCð`6ܾLY#$7Q”t;%AJl (3=uIMmeHwFc%!TVU0 6>Ԃcu7֙{3{X& ]vEDy!;\r>YŇO6 52q-\JGT`mg YEȄ)ƕ[7X4Kav?hY(C_e46_?#xWt (S :3S#<"ҏE:kU^[j7`V7fr/8!Q$l ύBl50Ҕ\|Ƿ|"ܥG*EzOc#XpTяÒl¼s?JekNJqmEH7 z0| 쭪#+|v6~74H څNy6p!Ap_;HTVS"pL=u_+//ާTӵ$^)^VMD⮛G=-zh3uO|ٕGW1Cēg!_WP*@+eD#}r+EFNxO,82|<^NTvߙ@899 fnC T2N2b$?*F ͺ>=Eb1ˊ )'ʩ'BfetcC$$ _ژpꨳ=/G MFTֲ2wTסtzU\Iۥ-gY4LrHhm,Hõd!+P ;q߸% a;%2@LPSsh[4VeHϏ!b%u$$"@vL~ϋep\I?Zs^B4p_qMv_ 69cn18 h@\dX =}.-hPx' VJz."v7O y?ovJOR.Lz?-+)ie^`W*&bLyӘt//jCf.JSRYi[Cr_9櫓~2lk [hB":}/d^wQl'c~`@[>8,"T˘*Lm\/Z[L&K)NdI2a^iM7ԲZiLX(H1kJg{`Cl0 < qҕQɆNZ$pTwXA#J9Y\zLz]^ (^2RQ'qa`߿8L $K4\(C6W+lmx^!/Y;*%xmA4bѣJ}erc&'$pm{Srn!|>(&"( дre)#넂;S/Ϛ^f Mqԙ׺3҉3d򶿒BtZ/Sg;ى=l-6&˺0iD".0bXU]zAl"_+в'} -Z'rҁQE Ȕ㪷Bª5" E~l4fO[<׽? ڀژ AL6yIVr'f仺/ '!I'-T4L̏Db+ӥ6f򓊶j6Eٛ^sK8h0c!U O_ r`9`+ !bd}YަISVm\mJnƚ#Z32tLO: /xJM3Z)6OKeCdn ;gTLqp~X0n!?@c)OɁ~ 2f$&LÃcclUachJPApS͉d-oz\Z Fexoٺ<%+[S /I ]\I5/Sj2a7;RYYDn-ư: RGG,@{.9wR$ةNھm@?bg]ǃ+e1_v&YsZ(X9_߃6N8CJ䉇HoDlH6I)E_Ȍ k/v!&WCknҞ =8{vuϽ(!~8[:4/JN[ͳ\G=42ӓWXS]e>s*эM_p'\\xgWRv"X yMXZW"i7Քz. {i0k)=,[h4<¦wFpvus]] Q+ N0eLv7Yk1H^` ЄD>)P>4KJ`q 3e?.G0fr+c{r0##| ]2F߹N[n D;,p%0Q~P:B ѠgxQgl[ǵ_+ꪼ1ߨ~P5\hcAq:lf yQ[]˰t/iJBBt֋->nilA%Gbtp6qYٲ &as˦OԸحgQ5_:amwJ0\[ b%);j3@65.ɠ@,PX=ᗥ@#OyPtH()eov5-E 5ČԈbF> ~N&0d~z5cǫ6NaSP>[źG㜺YWKk͊FIQp>Rҿ WܷWr w@j!Sϱy|8› r3Mf1ǚh7QտS/@)wᒸ~ę4Bo@NV=,\:efL Gol4-w7X!9J+߄bmQ!;uS̬;s9-`7d_2Hk^tb굮c"R[_yQXuLq b!XIRE6P} >.bL EtcH[2 ClT]"J<-$0#kI~Ļ2Ԧ9.LN(|=-)GXs %M,Qs!ҌڹQ\A, 2'?[|*-p˲\qm▿!I.5f (J$WQ:-_nݻTq`" Ô޵#'y k֯,p䂮!"3Xi?KCz/{itWMZ)+$(O&%4H Wr]w -AQ ?;$'\l3Z8/U8CZ-[EZv@eiqߖe>wR#@y4,BА|MsLc9|mVߦpyQ[RU>Vj"Uq#޴y`cfB嘨jXPL%AL#~'Wl Ůcg1[Gk#vlj7va` a2qgC=(j(":/.0f/ r2 ,<![owR ڔ% e(&J=(}[#M9 y10>\}9wf C%wfs٨t7YFK x3CFCeeUfC=pug8>5$ihŇWQzip'sԩ*'n(&j1e ҂._d,/$!e*?Jڊ#kJwS?evIMk*cw=3\M? 0j%ˎ ""1m'rzpr =úN?-Ԭݸ:Kb:9KTVFBߣ': FAWd8 EQ(oH`.eP-bS~ȉ^tDmUpWٹKo H,SC9QRsD⦕\z}ĽKWXDHwdO*mI.̀ˣ;'-q-I>V'w#q7/_eqW!-+ߎ[art jO lZW߸3]p]qɲd%e-ކ^s?}9^u4mIB (g]'Vh3++<1Jd9ӝ1S#Šq"<5⤆^ 8eqъ<'4ezqHQlDꆗCu8yߡBSY` qşK5+>2YQeWqb3e+ $REQS~J+mE\5]Q{,ěfC/ ykfdʋ)rw9Fp*v_e b߆t&z@xzw:eapmϑh[!Ypx {L PNmJG4̅~ bx*/oGa4q@*b:as K7 m1O mVOGyS`""[̽&+qÚ v^<+~SDׁ^ Wu5i@_D?D {cw/F'L[ ρSPd9Wk-0 HKh`J12o {REIdmhQm5RkZzGZ;0GXv3%Zsx@C>1}o`8-'1805$:d .Ծ&r!c13#/bF1JAbK(ƠK>DoC q?fM&Gyy1_%ll?J"ĉ~@u9"&I[훓 N)*1۳yyj~Cpd4D/xdס14xc͝f֚ 7a,'o|K,xR(Yכ}ѵ{ LtO4?0G[rꉷ"d8z,ݽ:$EFJCXOCɋRm)/ 9e_zT" 'mS\I;'g60K~lR8w WOGt%ziwEA81"uVB䆛OL֋X t0'c Voܧo U /ygZҽ.DHH, :`3X9 Qv0XCnT `k?a&/@ H4 FH?Ro΋\PZc,)1OWܰΎRyRmcaY&{n ncԭݾ%$ ^" '%˩h7$1@ߓk/kP6q_-Q/l'0j8j ׁ1x\^}˸/M>9븙@) oq `1ƯCA|N)MȁM*@fCf41U,d ˚Elw#;"A>x%fCpfw!ruRu-@ g/t-n%'pfBh͵P8&lqӍu5Ժ`IZlnXc3k3lyWL4%&\V[fu5=OI>xt3^K)9DOOR'rrƾZ+^p~ x6]ldRw8srV |lHXbku("+B:@Ԥq-Ci3.AJ$]R㏴I$Hglדu|Α>p`3l;N>}ˠ"8\۵R =2$#2]cj;[^qt]T>^4'g7 Aή s%GZڻ(3$'-j֩/HOtTbA<858!.#(hVT"o8D ^ھ^)pVY]E k*@ [ &jCC $Eaާp[zyM#࿍f{ *)_ gHKRH^ȴW1ypA;Es6|ϒ#4ԁ򧜯} $D&'fAdN(+rֿbC rWdam9L%X52GG3n1]7q]} /gG X2`e (ql}o^F) 9%y>&ę!3P[r@ WQ 0VH;?(JJ`.,1;m0UOPώb%faf2-"il??[Yb}R!EEu옣Q^&!ꬖMtf,*ǨD%XgT鼊I|RHM$6 o$.(u@b7QQiיݛ2O!{sO`!RjCoT3%BېRgIM|8P T&E^cX:%X.<$;ZX1>٪!k5z$gPn8!FVSTؕBr$=_\GBWր&btU'͉?W3\-ԌZP>9DJ .oeв,scuph‘N%sPtLd$cb颵!֜5lКmTYoj|7::1xOgI6F;Dx@=4+cE3c|/= EiAq$\3Kӻ~OR2̪/ڟI]q¹GQhec6JiFý/,;"Sƕ\UH(*ЊƧ jv"tC!퓌Tz:dr!=B~ÎVj)BxcoX!BtZgs,y{Emth}EKcTҪ$xhLafU9vʳw&M9s%j%ŋfp%z~[sYr}p L@:oz B6&{b h )Uئ;mN\ ҬҰ`KZ.Z z fJG=E^uXzqx!ut.XPhە;:4>{Us%"=K(2R9An*kĠmTl^]]Kzh%[R`QHAALe_YAJ;"{>,f /Yi' 0'冾Z3SBԂepL0jb,R!pWRna/|2@e# z9}C:q+ۢ3g^۔mtgG +UZyD gB՝d*ZN$XԸ>?ι oIZw;<0k`8 Ѫ`J%&v]'l6B@_(F#>vCŸz>56iXJh(S`cbE2f86q;L (DF.-2Z] FEIoAB-ڡIu0qAxڎ[׼ wuяXFxB IBfw2>,N #;lT[Z7Hs] 1!+q ]om̖J-i{.#ry1+{r8 6[݇Lj(>0En m]]DA%7]o.K(ʸait5JWB=blruIq|X+[>pp^y%np̑(WLl/h؁9t/+,"&??ؑ码XMq9m_ƌI_M:7]K|pdխ}e)nfcy$^0i!hv4Tn`7.>Z\+7!v!|ع-ێ@¨ ϋaͰ֔'M4 BH #i \$p~) :|C&qyv"4p "jr}i+1J矃gUREv#*N!x G4[hjΪYvB 40y%Q+sڟ06yP[BF2}!ѩ} Q.wڭO"AT=# -Oxx*iOyn֏\t ,@Ub*6%B7]ڌC}ӇE\G ?=ڱ}G*}Vfץ:+k'g-P_߲IPc4aQE@݀~n ߜ/ _ϝ5t& GR YڤHQV +t¶?u9_=Ə/oboDXs\E=9=ouDg\x77 }2['8kZU2[Ikc\-j[&vAS@}j&Ӱ'-xZQp211`$b7}yo3l%!ȇ|tsļ![BV |.GVCp~#L )y+Jԡ^FI i|AʯuQ6d Q;Fճ%i2[4GYI~ihqB,᣼zYU a6 } y/5FvC8붛qH&h&j>7i<A{\n`R?ոemu}!r^@Ȓ MIUໜwn=쎇"x'mILSfcBU=t׏~-_&=A>O+&6RJ@b.h*4/S= L|g6F`gn]nNR]B%s 'BNUlQC髾r&ed%ھ-ygvu~6riJ }jO@T)?ѥmYY{PkTt=3m!\/`49 1_?| &R.øf*  //A#Z_f9`eP02bߖRӁl'߉ws&:#.u)5YoR'bI,r>Qe~IL *k;/Gm)omyr/s)N j'L= <#"&wX[n@ws'jfw-5'GN?ӊ)>ڧ``&5!k}u1*ycSJ/l$bZÙ!=] z({Qnn}j" EbRlį{`0%lC_Drz~2أ qQlet]E%|SG_<'S`]n*hɒK03YLNԕ]lqX!-ONܱgg|^⮋k4ڙn " j"P~TCLv=?&pT^^r9tMG8Į[)<.~)-^<7 cߊ"߽8Y|5ƹY96x|--T.}Xu K֪g`îY0ĥ{H:BE( dq#+ߊ/)L=:! 1{BWDEWpX=Su@]tC_UCg{jyA;w̏.Q`dˌrHo U֜^B@Hl= u?mGyƟ jCE>Ƚ\,?i$;̫mT}].TP:J׌飯G=/^u1Xvo}FaշV6MNGġK{u ]!pWr?~:@%5:f~˵wKic>8$Yt3C|uZV%d?LU ?; ds.ǩjT'F9XYxsiVO3-Cѻ2!me%QqӇ䗿ҟ%!P:;'5|DIw₇A= Ke.H iHqAAe"W*[W-1fO#c}rinEyƾFq_Ӑa,RFUr3ܺjxYc85ϰ -"djA`uca|>^1,(Ro8fSS rEwkT7*>M~~VwWhY`}@EZ3tITg$hj]wgc.ƨY2vZ@Sno>d,]F * vnqZe|r9IBIDDJĨF9;OWcvǡ6,aN~`=g9 k\CgF,ҭ$Um5~N-Cͥ U. 9j~JX&Ȳ Sh/ULhb݅p j*1Y`cR{E|V28p zM?(.3t((bq+Z+c`f󀱬IB;'j^pQU8N;7aD wrAcDݒg(4@SW\>}JӌZvHpѢ~!i-&Fo?ϣ'( E!$i{B?m^Pmee}9f!Rxdo7YZ;O[>޲U# q9Pɿ| !(\fseKoDl"f dztl0YT ,M+,OEޡ)e7M\h_i19$:(oh}ïSuFLc)/zf@e`(RyjB[bmGS5֞Ds@jË'\j$|@䒛@zo۶A gzwɓ[JQ ES@OF{.5PR%u-g5nMUmǴO%|F-#(/9dX{ۏVuyZB yAd3Nxs4==.oG,%>`<&^1_ctcp7ìDv]_ "0ϤKz'$(=+Ăbe{0` zu+}l(I5U&j5 G~fz>Ą9鋇xnVޙ3|9YDlec@6S˫#ӽRih;q_w^NQ|_ X% O:?s&t`tVe"xƳ7XX&t1^搥nf*,i(ڃLME7br{iVF&0&ה7 s2LAkeUlq=UR`f0 +sv;Zne/ ;ۢTfUHǬFOEG^oc :Rgt9pnWwb}T`;2:\3`.#Z3-n%q7x{! BKoHMyRKKtC6Z Y\(!wa ,Ū qfݓȿFX/lQ9&Rv]S0qcW$mXЕ!EDž-'r[[ET, J0^АX| 2OW,9l#ޔ}`"x` fRyPa8@ձTZ] h~bi`Q~ x\y؛b?J+)9# .EE|*y^? 'NVx\%kg.@M׌$hx hy!/V]WXe c,B5o]c/Y?L~ "Fȷ7H.=i|\rLmoI[;)Р%)+!(4&-ã'.J!j\-2d/.d9x9_x*6T=Z$Jo$퇘s|UZ3$6^#6~J3jg-lY.JEVE-z@kۭ#A޶;1NΕ$"o5N>beN78,p* ?~rCbKᴿi>1𻅪IO`eb/(t۵ `u :r Fo^kvr~{ l u|28 +(EwXwUIBZ {^aQ GoĊN%v:GB:nEl5pXNrsZcjnW\/^^ڇKԧrZ/_(neA 0t9^f0;rYM^(])vk䚵%sQOcmqsG᯦p%ϤBS̮et3> (w,9Ƙ${4?f>OU0s|2j+!0.dޤsԐ%FT-0@>MNm)lgy𥔙*)*E 3 GG?գq)O_N*Fx{,55"#XzN)jstq)K` *a>Ï#OkjB2*[?6?Br Au?#x '`vyXPm!!d@z>J%ZMius<4u8}(X;\ ^~u\dlh%""kB 㼭>Pp.m$1욁E%砇ѲH:"L&MF63o,Dޞn)zN/}` tVJaeҜ_& 3 9M*JۺQJ = bKퟹ`mJh]m`1 :E'.vgiXzkQB냬n8ЩXERͨ,mmGl;{i>=-PCЈtބTƿMsTK!$#?&7Ύ٭thH{ <*,PwBDcNPyZ$f$!3[v4qkmB uiLu";L$nmw&xH)u+hwiJ&Vcizn(]쎜Mcoֈ}Lb"H K ,qQUw{ 9: b E,j-ݭؼߙfQ[YC Rc9!%{n\!\%SJ HLF4m[ l3P U:I|f{oܝ죓;q_ڛEqm-'uL%U2G h%G Zu)sH9KҤ.9:ټD5k3FoXq+LLiR*-S1COE[K6dn}kI遐!QZHWrj oΚ&',Wɷ6K&F1 :GO){՗8GAPνI%Ѡul#e3doC  {\^[TTv >gbY|Cf;ێeji1'b,t Y+crcN=WCAomF+BH* I1tD3$P؃@f^j;hϟ8|CۦB/ T[0kK$߮e6"lp#[i$wP$^DۭzjBNܺ=]|<NPp8 46i,`4tܫzEɤJ/~Ӿ;q1ˍU˔{8&WZ *dkqTL\3OD/%) (O/ b5Yj z;%2dSXq H»(WncO:pFVkFλG*oa)N)RN(s~`{`nl9 gfaP64RQ=Izout|Y`H㡺'\'x*Sҕڞ2w ت|M77>shŠ\T}o; >cS}Qtiۂ60]6jc5F-,5 .#Tw! $qQm>#r; L57@]fyMG%3w.Cr#16֭l nΗ9&=vKsicf /}k{0Ԑ0eyu.L@>3J^m ^&y{r97ӐᏲ1-=~^ZNJS!9W{O҃} nMJ4&:%Q8?e6 k[Қ ,@f >3y|4A|KJ^NfF}ȇlxVڍtv}x69qNTNE2Ip^tXn _tۏ6׽\0xDóѷ2%'me GxTcPFjd>bS//eر"/7y+0C] &fRA;kUtLbB,v0l'3M}o2Ht)6NbV{x!譻< =݃yh ɥWg#M?Ƭ=kܽN/|cS./8C4 ./O wD8p(PU,2~pB(bLe"^~(_kgaݒ2~YEb?|<) _JK'$-B1oUv&<8>gNXpF.;j_5ͺZ_OzFK zCkTZx@L-!eadXo)[ʫ5K%њXCNu:jTfY-1e?E?PQ/;!Q`V ۤәW$=TF<B\%ZT+VΞO1r<r Cd{Le|fָdE_j;vv,U4KF p<}/D$Zoo~Jn"æT_Mg<-c=aUO,dM: 8wܓf)SgYi("HU-T<ХaK|LDv4%p?#:/tr!5m $^&wxDžMNF:&yJ\yn4$ed΄X\`! \is+(~%c\DZ&u{LQۀ1]\Jy(v^o]0vP8}/)d.aҥ/nY8ftID bJCGY_{{ՄORӓ(7(j=hS2PLW[Zx܋a,YţQH vp|u@`BS KȆ6 o Y)f?ƚӻO#t5[b C?tg Qy˼כmG$ xR4Se2IW0f3"ϝ}V?rsw}U 6Ac犓\J7X.}|ph%N; Vh_cԡ~PBrӿ}>@Ꝃ?ll2){wh4aܰ%,g˛ٹ&9nKz<4OV9i/r}lk5^aw6XJm^0 Z| 9]1O4Ɖݜܺ3qUɽ֔6@nNlWmYGg*zx:ԑLE;Me62)vG~HGᆟqKy9KaxQAJksQ7<=YSAWwe)g_btѿJhlNWZKCIh/RaȟTM`^Q+>e-T*F\5G(͛HkVN i%ѫNlA;TeHq:WוXdELq !J9eHK<+[o]v&S4\FVybv?d4?j] [jW:7+zI10*ˤRe\/#P(F{v1{Mה)]{4b|;qB׺ŝ.IzjzyFpYU%˖ r2]Km!\_W-Z#E#'Qxl20`0@S=SBF]b͜:]s1" kz:;$,KA+h]zUm dVNv((F v< %q,l~9 l;:/[ TzvԏG: Rgœ}NiɷE]kIX u[ͩ<8]EcMkrgE["S[;2!e˧ -LzX/e.i j!"\@&/B9@]][E;qB/rDdPw8u5]FZn$U rA֩R +wSܬbV}o(WJD^q kgPRBP(>VK;]M-CRƈ͐6ฅ?M]AЃy hzm!@3 JI t k=Fr@3\_2/ޜvF^'/dڻGjK|PqmOQM'[?iAy/C2uqEڍN55<G4h,Y.gr69CA1k+V f*}=8۹8)f}lM Ccq[-[ uzJ<`Š.f4`xW[!ClV(*+I2e_<\ڃϡ}CX_'k.L:nᐇ"֜ˆ+JvL+6?yM#,qB{BApOU!J%"_c×zΙ_Ee9T|s'it_Ś]o~Whujfe`7B7X澷t]=Wݙ"pP2.Ǿ$@Sqዶ+{U݀iMS #!!<GfX<_PBRkm84Tz!GFh.}Z6mG4(g< ϻO-~>/(,j+c-g$NL-#<;bXQfD4,;Tإ ݼ\ /f+ Z  2dHdh չㄙ9{,hdr5^@H/sz g΀1)zGFnBPd˥MȞ7{%26ޭrz_G*]Jv43JHjc#~V FIB)wi36=N tk`wz(i 7շHkM72܊>zEKSPNcm:ǜZ% ѭ)bL( 5me+{1܃O`MQIU3\]^6AFN;`\oG{zLFs!8}wI 7.:AmHk-*!a\ӌe3x%. QX ?! r([IlYX CMIlK_F9r&@K_a?VYPDFnhEbOK$~nQcnf[3C<ס>%FX]-Die(=>6۩0@ZM^y(Y\9޺~rff3x#Q]Y۱.PApo)r `82%iun< (DG-C^ɽɊI 7Z6z@,٨.&AxD썐TvLXvlWXYFJpiq ee,]>CTs*q/[Jp.e4[y:IiiEʞ~uXrޒ4TWЃNY&?C' fZsv?FXgi6,S [&Cu9'73uĝj>hWt꒨aRz s_@̜]^BR_MN0Zq17vf"{'6SUW!j:4KÚgЛ<iV ?[ژj7-jdr!E S6ZqwV-5W6|Lhݕw0=U o1EjIXj:S^Vg4Ґ0h?)3}Eݴ 9Z`] ,3ZZNq\SʁFaj5l֓ X9(͌]Z3Z +)ru!Rdy+,8¯ )AܧbFgZp]{#: b QW}3k)<;|}TD!xᖜPd1> 2Ii``&<XB@ӿo%1`uq3iq/7~35f2gX5$^oNQf__ (b*× TxXn,Dh d|.I m+؏^Vm Ǯ3BŹd0膆p c N6CIZ-[.)(x|B9޴XbK7H:@T6]g5t. W'g8f3-gRot˿i]h>38Uh$#Kʠ1JwXLV ԖnRz +%GЇd3L:HiPr(f#PWYm*dhoʇ!E[N\u*h"B'M-ZxQʵXņm:So7Hiy;z 0׻V{^ ]Eyf AԵOBڂYZ:*v%Ru3:gHJ'tF-< o!#sye&f$ 3Rfʉ@> ,KZ|ƽ!X}CK*ql:?4K>.sc3olzLɻ,"f=rI}f'[=#If7!U/3ƃv,7'tuIdr(8; cv8HoS91Ջ:W2u;?rDQ]qe?7\˦ccXȟhP_bۚwTɮBkz><ЄTv5Fgq.H-r}ST>{Rvv\;1OVU8NN@ Pz,-k$3?-|?]+ؾAajEOfc-Bx$TfoGO&qpP7IDڊՃ1rd WJ}Ogv+(γ˒)7K#S68\0q(XuD f ,#asWB@$4 A&%Fʶ F9Xr;q|)8Msk쾺V"Bf+@G}$|!ܾ% rÑґQN=*$X_&GOjն]X# "TڋjjTq `{JpBdn* ק8 8CBg p;$$(ֺeB|KߋDr:cxF(Y5`Ԧq : vZf֞)s<󲆄Y\4,Fp!fo*:첁toq( *A-YKj7mE(C5  +zo{cm -I# .?4+܂cd|Dzdi\K'a"Cd_΃<~ Wz#$=dݿ $!˶a݉Ln&|jcdU  Ot(pqXGI( t "U/'rzlԶmc |~(&A-+-XӸq93%M&5m]@ҿdžσأ]0'ٮ~KA7q'.>Զbay@ st\cob}I_Iحci;5QuF!8v ҏP(Ag2K~fCYO@[[b7To ʆ|fnBͲJWځ AY"f0QE_ÂBe|!­n/22`nH@mF50nc q^S8h^9! 2PsiP^pH0wuʩXZxU?P3Ժ]ȼɉj:;< Іᑆ_#/p%k )zg~F0X2 V\8пq C~}v3 PLV\]gҦ\%鴻6@L^$:s~4{ ?I3hGA!>?#O@+r rk8B04gZZm<5>wAڨYSW"T ^:mtvQ? QrʸWMfuʲlMoNaY JqOO2Ü?ËPLfshK^ &]-C+6 e{{h}+A=/f𽔗[pZZr@8X`I!s[IYJI056A6HApca="^_E2>h&c>iGud}y9n`ȇ$X3>J%[db]kKDR^{ix$D\/]:߇}} QPID44\=w-' {Jsx&/Q9oޔX~'[Џ"h8Bؤ "o2-{Y'd/]^xu5ԙulb=Q}Ĭ埢K%H9Sq2oz^S))=o 4 D֎̐!{q-e(\9%CMs\^e9EM ?d׮bw5 }|ߡ:&/ȬCE q!h];;>s\!٪}n9phK=k@$Ja?HC)<"~KE.fn:Kϼ2-0u/XL56ʂ u%|Y]ɚȵ5Qv=@ 'ݕSqvs^/fw-TCWIm0Q)vnOj|EMeto(D-@h0uQ``Iޱ;5@ W#9p2]*b{R}üN9 *TZo+{\Mg?( w磏'&riS#ece$6] %z$XX&JxNcf6߲ȡ'J,zP d@nc`"8 E&-ZN k@RҰr;p6^5νЉu]7#ꆽW0->ϾwkMֽ.kui*-`mwqj I)Yv+{A^ƹ}=twe"ȃ7!eJBsI. ]A^ j[$b#1r~jgrՔﯵ@Xl_2p9'ǝsd;Hujz}CR( jSuTp.IL Xlgs85u'%7'7"5z/((Zth t]%>DA4*DpzL=`,'&AaB Kp&{Tu`V6 SHs-@?@7  U, ЈgŶZwyĔh+(7ǂ `a&(~ZMk[RI@r5oomr猪2PbPC!X{V ,H24#VdM"Q&֊2tXBT$l b}êTI2_7}r/V߷H8s =@b@ ޥGZ+ߓ'rB~K풹1Fy,zd\Yl|θySteM3&`& C  f[J `ZT!8:c7eTS ǿnuʹA -P0xXpaH0'wEP>$P)QdԦpq, >9o)¦_zwAO9+G[c|CN2dNO9X̍ߞt0gZ6FK|chpm/uݱ`OG{'oĔ_G3 " 1w`:m:?Pk hAk3DƀS Rzӑ>%nӞF4ކPMKYPˆ-ֲo+\MS$@PFJq]ilNR#h?'rokJl̘9$_FkpB đĩ2c@#n/;xB 5mƸ/7JP\l鑿'qƨhfhMs2USO"I^LynYƚAwa>Z cA*܀#rCix˰zt?/ & !n0^k˿oLŒĝOgF&U \r!UZr_&׳9u~L_Z~MzR^%>cө@vˎ֯pkf;X2KSΒKcrhB>y} :1"g6 bE-IpgAS2ZANbVIvLCmF.:R Կ C(dHIFyoɀ cW^ABQ}I< fJ$tP  +X'1rOLVσ7=,?}M/}mHu.$1@ ٸ9?zzab2+<]?.&1u4d! !ܣ 8x R(?(dOџ5 "|c}7_ To 6؆M7.t7P:3}B7;90u^:9!OO9;MxrCWVu*traK9Oo@I'# D߀ ({}dBzRvȔ}\"XGRs_' HgZav*ƹea!,$^~yT, }`s1<+ kwURU/ƥԏF1M3WPDs{-_?%X}?v'Ig )$uo>D֣ctj2`$>Es~q@K8 |J9 +8{J'XP|2*t k&-Ŏ8=dhvpuR>u*Җ(>z7!]g`( )/ y.EW=oIi*% n_$MSt BuADC1h6,m53LF4_>uFCb安b(=ͧhEVCc=A1Nܿ*"8e=O"zqz('9p#+bZ%XD[NQ%cF1f$,h,㕢H<XR,@wl]v=!Krsx @Gv+ٲk OK-Z-հ Q P 9jSTuv^sqpn6RU>- D<4#ލiѿBxtjҰ1 U ŒiͷUYgw@'NqS팄Uܲ"oIj=zᑨȻj{-.0ZGXZ%!s%]+>EE+MQequ*н=N/;:vxEZ#AӐU_qpףc`5_ G}+rO?XH{?:VV2ite{Oo+nyK વdoqaQTr-ZjsG~I=$J& ML`/s 䎆(Mt2ۍ`2^٩XA@*y_Xe+:8nIpz"#*5gY'\mָC:X`r@l-V=yz.N"rz$!a/pqc̫u$/Œ&Qx{zѓâg*wNJaWZߕ;I|6bH1$Z/$3MU\Poq-cUOکQğϫm}_s:D jUSG)N,bT,9/KKGXg1K*6baŠY1uheu;GW;=YwytrHCh}l)?3i&!apc!=5ˌㄹܴB:]hrI^G1%,yPNv~K>P udo xٚsA3PWʾ̴!tiv\ 3n JDk.{["F/x:Jg(,a/Ϛƕx;ZʗCHjqc{xT7>q0`iqn1[:$D”<}8aB &w5Rt|e6]z_N7d\Ƴj3/ίb- C5jl í?T ]68D؍#)H2QTy(U@n2i\-t(M Tr3zFoR5Qf.aA'zc8+ JԌ_OA)9SH7 -KrjXN/<ȹWiQT'}STUBS_ Y #V0wE׳@r|tSLvzN+g"T NxM`J4tMdѪz˕#m˾VQo#z]WK>wg u׍7{1YTfȡ"qe[s^bI .&띹ѲW]a1Vu\ NS GpdA˛Te^m=(][ìv@Y7WE$-'{`d%(a4|8@CWۍ(<<؍u'X!^_GPxh-ip;K'Kj$Ctڼ":/A慷Gu'G.b oµ=G(^3wBO #6.e:F.u霤fSڱ[ MȟXAJnr$rgy0ĭbۉ;(6Ҥ)(T=GM87.ގ8{cFF6b-$R87!VGrbJBFQrtRB?N\k>4^cUjZ\T _Ar jVK62؄gfdeF)R^`d3sاI|!ِX*\Z(T38Xa$*um5,I.+WݶR ("*e@[fh'kTו v0*4W>y >m߰3" L;T<ݾ^PJmQ{{DX.ړݔ}E2 njs/JglxUTd~cKz]y[ Wש^@D5,2/&^RyL-^$](_ Wm=%ύ<"528L[ )w|-|㾟aMhkb}ɽB@Jқۍop^?~<ΐ,5 UT2F>9?~ŭlQ/YI9ƤP zW8WJJL,f9X!\ȏG8.EdZ3q:|]+!XͮJ*T6l:)g  CD5#2 ݷU6֓? E,=HXd?,8 h˦-fD@0O+Ov|c{('ՅFd`T::)\ 70F%4Sld3 փ!a]n /ߠ~Nϩ-.b,yHчr^oٻ ~P;ˡNDmehW69W CNaK zo8hқÐmkt XsW> ŕejb[X+TZ)^vb9DždhfnϟT{7xWVYp7V>1"E!;(vaC&cDY~L󿶠qݣ"=~\Ze8ȩֺgF\/B/6]BN{ܶ> uV9)htpkI`%ܪZD6/iS38wz0$ cy wR-&6b+͋dA^ZӧM|j,Ugd'#;:éaZ)3fWJ'$.z9c8RR]뀲ß)R^!A;Y )O1j1xيO/3N3[Zv=PXċ݁BTr:{cJj)Nѯ0]Z/3FeÜ~39Pk0྆T" gH0-?|WhbF/¡C4.Mi_R۹S|wV :,fkz[ vIAhMшH(GZQȺxy@"ߣ #U2;tPi2go9Ӧx\ޔ1\kh$ʭXU)hE6hgVFi`3ٕׅ!U*z\a֠_ V6N1 (E"K }⺚e)Fqܪx[dPX` >jUOg1W%`liM+)阂Fxi(5H PN\'vQ]Ytkj?fYG_zeeދ/lFŦZ^: oZ!T}ZK69̌Ef!JT|a*dꩣa(6HfקWX8{r8 4omwtW֝I&e^K8'%O$I&P$KɘO͐KZ##V /u_%XUҦ }E9T2\`7ѳAuۓpL6^=tkiUFܮsk>h2]oÙ/J>ΤhdAu~~Yp᳎ ;Xqh EwǸ@R䳃-'BO1hfgp07:Fypn左$>{׺ͷ^V>M`@'V;];| ǃWlWQ2'˕/2-ɡ+J .17-ztP}㼱vyOѿkt[o`Hкю3&RG:8''kd<3wuE?5⩄OrmsF. _QPk8 y@3$L켻1`x /qcQtJ3^ͪOaHlp뚀3x#̴fbH]@Q%;l&W9ݡkBg%ws䂝&z';a@* 2 opîM |-Q9R+d6A/%_CNh 6AfGr7-DxmO\7J$0]bj㹫mo@s~BhiS{DTV;D.'K5?G 1ZM"0Cy>+W5 B ;7I56݈)͉3r*>ᤉlEOE4e^| yO>Mr]ȋBr>W ,2[V!(lrl mjˊ"Y`+lrF&{6kQ%kN7࠷IeBSu.[=6(E]Ҡ~M %6j}pCi|J&/SKx2t+`lدzpzSpݸ{=aȯ`q[~X\=cTSm_3B{l@|yt8գA*MMKj ]R[ܷJފx(Qփ.RxjJ `߁%Uy/!.0g-b,HEnD 8ޛnqkKOMU Dv$D %s ]rv7d )>c)㓭GFenV Яgm$<#ۆI1OgL%&6>}2 愜bQ h43c-KYUH"^g7%;ާğt59qklLPFVHNE^];A^9?F@kH(wҤ+:/7 IT#O)~xbd,> L'CW$@5?!wYPh}dPh?QJjx@%zUNpsQVlf}Y?lXj'Vic+\Tr*~4AW! AV`SK]~RgDO&Eq[ͯ,\2EoKn yΆ_aNy#嚅~7(o. P%WMT;c#rqL,j' *Ґu,a6w'>H-]H\ h:;AN>eb{e1)˫lY~hz%QvAʚ+Oȅ3`.N@p܎j,6Ed%r6QO {ٿ5͗Vx"2MP˧J[#)B$)r+:fg½j~/~yk~"^O L z0HPD9]??4,dTǚAE{Xq+n P1X_.ł'+~xSH^eHb^5!%dh#$j$~8^)KIBڃUMh|fJrҼF#lq5eS6nN4558 y*,h@f7?ִx:5_0{_HtϝZu/ٿkVVv[mPnLw550?7Qfrjh`P =: /iy7xhLVhn 'z2y ڤq76xu1;wM21*CFG%&hQ!!rMpT]_+Ŝ߁p2]! *s0]#u.DŽ6e+лgD5kDemSE"P+5ѫ>_ eѴc)V8=?(/USmwr%8UVNpRe}@Qa"mnZ_b<?M@ՔBާUnȸ5z0$m>~ZW\dg@?d~xI {'ٿ3˿' ?Uȝ\d3c*@Ʋ%%Tt-PC\O Q]&X5Ecg͎ ns{U#:xLwFa&ZPM: xJ^ݣG%4LIX?'#@Rd_M{`-UݛlZb{%bMisL3Ni|<ĉ8Ĉـ(s[r%2e + 30 !\P6LYnNĈ'#]͇0-e¡XB] l3R@ihE.~_z[ڼް ~c| rI yH^;/mEܤW_nu&̃/ ㅟImv9*ӳ:< KPp[ъMs4A,[EI8ip j) k( %좑 cfj#Qukv,g7k }}g -Bƙ. Ek-9Ugbr:rVD*LpPnZ81gQM8v_{7\ t~уvn޶k )F Zp_2^7rƑ?S1CW^3:c(hO*ʵ~lf=rVL,HP-4BGmQp{C*D$udJMzk~Œv94pe_Ue]P ~Ջ2#!=a-` ue]~Yntd}J-C9JnD=WɵUzLaKO%rv<+F#AFaB`]V2I#6?G¯BCDT74emBNڱLoGxi*1.a{SGgEiqoԸ&I?MB-\vP44xզ>a'99Bȁaab蠖 5BcUdwà6M۔A+iEyϴQǬBI>BTeg1P!w۠OYg!\%Eʟ-5|$Q@;%8'sl'CH(+;#[G xLHߕ 23aeh11?(.Bj`UW]mAI_e%ޠxI ȃ$63얀GJ/+!:she=R;MI'91y|Qs#o.TK Ϯfiod추hG{w+ £`bU 6碥B3}3`JZ(Tܜ8zT," X vڲ P,g j+(N4CRNƁdgMR(FIB=OQVmѺ ׆܋YPy2܍]k^/;E/+;?k&R#4ݙ$ǀGTAPSho4e/4=liZ7翠j ұ |f! dyWDTܡ*rJ5^*٫eEzmTn~A>=ջ7= ִG$Mx/yi|xMB΅*x^sЙr0zgS[ڄdQ&3GB%yz**/y[žC64h Դ/~obycK``s鴼YN?Wg7`úu_Zz^/DݘvI'֢H mτyQmIr@%jJgg +QM :pqYKѵc6~s݋SMfV,`,N1iJ6aZ?㨃si\Ġ`u,At٪Ez"y^', Q$BaXYފ|I¾E{J]r]K$EvgyZ޲W)x˰Ră@aʹA4pX9Ԝe7ʸ^|K&/*ԒqP|jWyg7_ ;hP5P}c7QVP<=\eۗaN~i| v/,hޥET9u4V #!_p0 ?d˨ ;@PwjAހ=ohԼ{+Î9G~$zFpeJ@w{6=Sk"dóv$²e8j lg4^ h1H=*d( q|i)G2I}8#w%(:UgVFaq`#."V섻վz-7UO]3Z;&WJ!lr=;UB%(eft'bΔqG$luAIIwc2ffM)A"XR;^!~ҋV̾ohX|0=5>%ᶪvֹHSft&'.{7e*>%B57Tz B ݨ_kZKoH.lt2 Ah,udb;@{BfY=D{S}9 W"OAnu1~t2A\1{M]V{.cǚ86i=j_"0ֳfeÚ̵v`YF+^5'54"{}f#O:V*^޽{oLϻǭmyh/mA^df3@&,LcٮP9oEmkY{{lYFfy3#GfDG*K=+񑰥YK٨mD1t-"+  7?٠."_,mQg;شP߃w"f'0|3YGjzM(m͹SmM|C-G/V \}W3;f$L,~$#=#D0qm%fnV2 vKY)=ՏL;1ReRm- 8x[Z7*ǚ$.=h nsؠdܱ8$OS^㋠7N;eiu@38XD--V}b$J C ;x*%Ok|RY?D7vty7UV*10`75) uqvn={\O[|$+E/bkiQǗ)K!{n#Y' x3_3Wft7@툱Ix(_u*&L6WbmM=mDXs eʕ fㇴuꂸDSuWRtg2ER1ó;]*g(ULfYp\-gb{FRWeO/$ SP^hYV] q~R C*UÛf84t$?Z?=]כ9.0 }!ZDEUFrnJ8`ny]r_}6AiGo!84 Q dKA%nyZ=Эښك\,Γ+S tQICӶrGiHHJ{do D2E)"3;ݔ+d-X/?T+o!: )h }Y^x\7Q(+/$@US.2x_Mə%&հV=1bJd; s5',(m%VL?&GE%IąIrZGv8 6T#J&u_R!2矧 >'-(עݙлf3ꂘh^ns FόM{npSA1@Vd$]CkyCM5^;6-\^^EF*ח6g8Q&{|N裱}b%).ԑ?eWa9TiAx8x@8|"T|"OfeRW߈KTғ.uMU>06^Әi+py[P<92K5,Kd-/M~V&Kf`Y#kw@5}H?‹'Ik!<ҞH8NjGFU+9İB`o_/DhтB_ӴXozM "aFѨj9UftU J0v [a< ۑ_5:j[#Kaa]}pJEb~);L R}LTCլFgvai@)W5[>ov5hSuFP ew{iVLP΍ dSH*T`g[J;ݙpTğ?AFokhVJ`jؤ()xOGp⭄ԙ582N<'?6{k\7Dcu.%QVzM|#Za'<'6v~K|yWqGZ2$D];ȧf>,3d߸bNniME{:ҧ"qB 5 - r10$A"g` IVPi"2 -["ԳP^t`]XqDg_* ,X2nLDܸoi LvP.YC RSy tb|CM"]²D>mW[FlR#ƹװSqՓ jmR!kGF6Y(`p멈hWM+gkU/̩6@Zns..HR:>M#X4ShvqD2 C6eV<㣣l}9#e&FchR$[$scy'*n߃ƃ %D=byl`EC"w*κ )K.[sA oRk{^-:oA?7qB ISeg*T$4,u{;̸ۢ.z(erb7NvaS T7ܜ$1v>{Ul |-%ctbgɄ:%-9!SQĶ.KR#+,&(^փ{Y bA6G\@ゴA.GPG{"Sx@g2q05*֯U#h֫z䀹p@w]i`Gɉ^a=_+1ML^ҟD:c> VbTD&XsQ=U V혅r׳dJ :}WƂ86(/uo=1CČy}SFW wv>ȴ uB8<:swM|[ۊi@-v7 o/ojQ6j6qf9\Mg{L )kcƣU&ȃ)Dt`c}"h^V{s+T~L=bQ|4L-ßHDžPæ 8lLW;A~/yʮM~]p$4N*ztd3لE*@>.2Len*Ho$1Wlhⷺ~(@]=OJY1om$E{X4 /4`4- 5l{It6 eԅ1d -ufF!CY`R}:,$ QO}62x\URaD>rɰ1eaCh%:u5-o2S\o46Ű= xv5?LYL=7XMqzE9ߔ ]{. qsȣL[FU-Ri.1##~]nA^Kiv *E>Ϛ ep}=c{<#K1)€{ t #͟1W_' yO '4 c=qOӏb=<%0v!6Ʊ)f\HrKb7($ `Uӧٷ"%@["ijĂTچ37g]/x3֊KnEnMYn _U \41; G,]3݆?DQ+ 1˧"d H1ԓ)Xۄ,zFB&1<3I[m"+\~otk.6< 3eJD P=\q@ZH= U R UFBҥ-2̼?_>*jxbliE6AMMY&#?m"hihf 3G^RBz+sXg 77g-]cWH"/8y5 $lΉln-@z*&̘w)RVõwB͝W9b1MP]vS.8/3KQj=7:5K_i1%Y)8f4C$0<a ثz.U]a%P%(t%Yw&z)m(ƠCLq&_sl0OWz`,ۄ=@H|gҸx4LIZ7FŬҢnm5?M~JJļb/2܃HZH¥%')"܆`cN>S-Cdo3u؉0ѷ9w%w;'ID,ǢNb#D6T1lM|{cF~ ﯋KZ|ͼri`yeNë+17&*)G'4$MWМ2g!ܑR"=&͠IUZaV`@sW?Mm.PZ@*w ]Dv${#i>œ˹m?Bդ(ꊈB)lLmxf-_7PW,Pq&RwŮ@#+Pٓ!Q/Lw)Eer0oPce$,Bi"ffRDm"mf"#_ ֠_Ʃb)WDKX'{tz17RSF5n舙#++G hCѺv#D(.$ۤڙ`H=3CAbo%M=WSjbERhQo򻹺DzMEl\` n R+7@wk+y*iXR4}w\%D?'/s Җsd UWՠ6eao璮&b ۡ/1悳D׼6na'XWd@JBSPk>nQcqEU3RCSk"ȻN:>ZgVZ:{ jˤR &O(=XzaR~f$3ޯ;IBJMk8 w3A.kuW-TۄeQ@=E:>WJ0 t[Q&4`u5tdv :"xrT-jG[BY6F#9f~B x JFJ[ C.!.zc5 pAlGq<#!J{}~vDA9hP<Z;J3qJW {3evl8% 1z u}u5oqKt FZ&'!5ڬm4xPR=+N=kvO.-i4Wʞl=C6I?:RZ *7Z} OK)O$(l)w8]4=BuZ6$ fL5"߬2mHN\[$61Gs)1_*qBla.%}DStF`P$քn^5 O dnpFӉq5mmfR$a95}2Px]C|8z%o@~I DCZ1)jΛ6_~`/_*D~&V-8tMޠa- KSdm+y .#@lsc[|W5g#M/ЧqS!N/2r '}&M31'8vsj2 N$zo<лY3#vL(2;Qf'Q=9%&_yKh6@JK Rd> 5@j%L{"Ca2Ѽ h9`۪݄̰d󖶛YB c.tMg8ZP ې$ W$og275bA˿JՇed;+$tLQLjES}F5a⚳[5{phh~VMD{çڶ'FM>ԳcT?Gj(tTbUܢy)Sd07/R).N㚙珺D6&wS*kw HYн0/$?ok)Ch2L\ء^)|?㒅dɭ$j+g_$SpRo_[EqǕ„<<8@Q6ҭ*-5ܤN8SPr Nz3Xп$s%uUah_WI f+L]щc{06RX"R_vht}}1 2ؑL0;|Bj\E<(z=XjDjn/Ҡ|}2̜᭩.4OiSЇMc7r xp)]E{X +zHo ^!=l6IFX Ί(?("wMu3cq qE2EOk2B';c26-O9|h{t1kN e_Pұ~B$(,1<~9 xX|K 0HatoE"/e" 9-}fśۜ[G|H}Pl`e.m dGh m=h֒๎7.S"b P"Nz>邏IR!y2@ SYl$vIhNwb3[ݮndi-Tx-0@$!)#5ocӀ;-gI q`s6QA,L?Ս_y;Ndm ka^I0.AtϷpaGP'[fdJ^*tAltNggsGܙb]\+<`i–.t)ٛ)V,:) ;gw6L}G_A$R ׈fofJ48d%B]ev*E[`pdIa*'LC6S ;io-Øw$zCͥpvNGz./\ ͜*\8bux| =A3YWIm3sbpPɧ.RiP❏ 0(Z*nmU *TNˊ#` !`|Q멿Ѐk.K64/HrJ?syY @s^$?sSܲ,n?h"VMLllG |w"巕<1Q'zޤPeo,4;f4TgG+v)MxMo +rGX钥,B#RGQyULQS;nW%TseϛrA,IUʲJV1ϗKuѦȶch(),T]hrg}gMe\'Ǖꦮ\n՘4QܐqgNCN*܁I.ܲ4L|+Sew.ToA+ Fڷ;a /+"5bR]D1u߽ΝAǯt!Ho!됑xhi9"X(iDD_%ŁCgOa?q/sTvAn6wt!R,{D=]obT0|uꟈOSǙY0mu|KHdZä=1|0]#,L0Z?F',)lW0i-s>`z;H$*d'{IDydQAUxRS-Gra՞V"gm@rTB'ESCрS7d{9\6'0KQ=p4 ߡ<5`/yʚ̹*=QĖ}Br!מaQj\'YBe )7cqē"bX:~`-HtcT.aY;Ebj `¾TseAoƁ BN0O+di_ J JNGAgKfb>>vj>ќ ۠do1+lܭpDa#h#pjO_#3dD3Z*m*dNfH{Cs\t_~"9{4cdenuEQw*x.? .^=z"Ju VÃltl/Y?G|ثUb\+Lژގ~Zʒ?R 5(*ז,B>{KK/`Li"pO섶w/;X<(VdOeg Su ,Kj߱_6#a>ӥk^HGSĖJ]+)EJ*!d_pJۖ G\ybG=-| '-|0A4I[4IEF*|SRFH]Ն+ &a+/,+;$׀tj|N-HslMHNqi&]=0zilTkuL1θd>#B7>ELkZ"k*BiF@$LxK򘀊Y ;e{R'&gf n,)tXg&աa>lh{[A]OehlCN-=dӼ8O8A{ W3:cW^\1 5{XS~+6n%f!' q"]&ps4S뢾Q>f;4Xt( UoQ<6r0nQDTkÅgAYi/LaP!9S5V 9dK4͢!˽2^ڸ5C~Iq4C7D'u#@5`+kmgƭ(K ڀ#ۦY \hNހ>"-MZ.K>©( 1;{-T5p9z"(p~TFd()-"`H\$>bg״Av 5owNslGbiCyS֝X ͥ]}X= Zo\IDTsX~Z,šnؐa7? ;h5#3D=RI>nkX9 c!y@E;7a^ѳ.kFQ` 7xTtԲ'lP'O>l9=nHuxfRX"*)Dta/f8FQ': = U bS87XRdkv3bRCE6sm!eYz*bi"w"_@bAĈ$ ڡUM8[`kC96ٮ]2ݪ<pUjy"3tJENSnq6h2EtǞ*g$|}ܞFG\&aZօAFUGP` L4 &#xz₫]p?zeOGWE88mD‰Zs '+붳.uɒBRBK^ssU\"}@DTIrq J!a-v w߸Fa 6Uln፿'+JC̿-7D6];<#+A`ٽUPh8j L7kp=(cJ hii\eQV{˶[8;X= fXX>kd 7+ Ҷ/u Dyڶ00 |lom-*7,5rR3*1қFk9z4)E+Sav N]$^ ◠a V)͒+̥mpagLk) r# =*FV$Qnݣ?!K+E.sz &Ue* -)IjqSپ2(jgd xe<bV8 ݟ70:*`?>aǔ*1%:mwx@/AGjy)㵛rpk7{Y6|E{7Z:̭o\w>D+5x SP$'+zsJ g 2B (mF/pqW!%M.Z$_taD`,ǭܒ[&/0Z^3d`HMhn}N5Z;`׳}8[{1(Krg{ [e:G 12w+YHFOա4B\Fز:A[d+ w_m3,).Z5<0R E Jt+ aE)n͚=;SrۭM ~W͘>'h]HeoR}}S'tu F0L˰w4햳N4BKk2 \|(Gr_w-fԌXW+d2A:G!VćT`).%A}ScB郭E6*UV=I!W0 Zn^DHkz/,h`mTD2BVasa4ׂ4׉ųg %Դ_-V""oW2V`NF8Iy;\;fXzݬth XfC;1F"u8xYwQ酨:9[rv$yˍ;g {~;2kB{WR=%y3G񖬈t#!K"Z'M[\{~fAOFgjTǽεwz<"BSJ^}o^msY&y6 S_mĔx}=3XF9VݧS_>3)ESOu_SPEʯ$˙?%Ϩ > kBq G: j0ۋ V[PYl$AO} 㷠i1K&J @$t>{W,c +̨[@@ W J HFwkU`y3&Bm8fUKm(G|:Gr$vbw4 x{%3(ىJ2ַ%kŜNQP'se4v3#bᔬi,VAtZJ}k\$H˾՛0H)6񚈊CjvANLxN.S՞{&sLѷ}u9*VY&XIQ_뢾5:u-1nUi*zGF9cňvl*p"؅\ ؒ%"ȫ3ٳqߛ]{dJ vڢQ n+ _݈؜"Eϣ5'|_]@}F,JGC6PtR6\Y‹wN=m>"-F+4gp"A?Mt6PTvo~&6a4+2x>ڼ@7%e{ !%;/@gu %FBs!Al[Rv zGcYae¶HH* h((~qקC uLnaʥ 8E$x֜sٍ0mla_e^̌Fx:f}  L:d":Z830[LuۏOa-OgP< ?zʬ/NfF1 h+"n >H z _Y&upoCQrr&g&Pj¯Mjl=(N磕;m;c_v /n{of&h|>gUl@km3.@ٰWrbI_2oӞfl&Ҕ﫹MP;mw-ߺIKGOlG -Զ(v-}DC\z_K˥h׸ cؤ{r -`sG b]v ȿ 10Wn9{_{Zʷc^n#ج_ Ff20hlRkOƁ4/8#`DB˄w\bUCZcO$eBj`DzK%wr1zZ|p'ո|@a"4OAY[3{)fO3Xl?U.qn $~n~N WEk62j7pÇK[b6 `!u+ ZdU>mM)XXUJc'2>#{߰}$aWG`1+Yr"9pM(-u%90܆0V'-Qg]*%GoDNGf6ޓqlF& %YHp .T7C4LW56 akO7n>O4/9:^R\@2yVt)"J%!$s}}%j6|PgeB}Č1^͡(Y|"5ydbHȄv0f趲}fvty~|(G;ڥT/AL`4X[،dnujlZme7lN[1tƁ??;nrNsI[lN4e{-dzf`[>zR+@[faɃ[-~C![$\ǾkR&uG Rz_^I/g KnhYZ"|s^ H\1$[ tiSWO)suǮGAb&n3緣zTIPciMN f։`VB rg%(4j? HaM^7[Wg>#Z5#׬="/ČB>lUC߯qM.Xſ_ÿfFN+N*Ы~KGQr3)(9el1H[eV|vw3i5 5!h4U p\>*U^ *b&p,loFcWZS`eFu=!=_`!8@={JNLVΫ?ҭ1G >c6ӻi`DY :p^_^BWXs%,dIi0F>8gu{^XFЙ0:F5~zH`poJ]u9 `AMOJjnm6r-v v*u qckR0QU5L a@@ \J(r$w e2MlE@:5! "SO!MJN13t2[A)T~rOw@bTP:HKu²,T>s\ uJsTXvLiLɯE͞+mÃ2cVEt>Ih߭[qID `'^FFƨƳTWdXJ`?жrBWFG{BFFϻ Tmz4)+Qp #H'uZd}UtZE+gŶ︌엗I Sywe!DE-WGf:-MF3|sl\$rۉuG8e:y$H7& UŹNPEbB])w^wSYbѮ&Lש:ՏlRL15ˍ6&-GZY^%w:b]. hUZ\!Yٔ;=u#ŏZ%Nz": .O3QzML-Y!o3-1>nFoUaUJI1DD6n FrP *Gh=f[P/ qtas}-/`ww:4zznD+fK01HX7TF)kp*NFTAlʆ*Ur"No'9~>QMtt.Ab|aÎ^gfe7HL)/1/sڌTqAdHAjg׹:xYshQ:?!d;c"ͪ6=%+ g>V6^M37KKZ٣!B4:,ʢ`hoXl pl{SV^^j;rטS )6k_to[>ґIRyݱ礡*⚙$ y@홗Pp<>M_.Voŏ?J&uCqlySapӄ]ې9k v=2C5 ]#+ 'BcБFO+o=Kn~ tkK_J2yc&K9Vx< Qu!KK}JɎ/*Sg2+_"&g9@MA8^q kXL:TjIũ\@XQoDDZJC?k"utHotw(9SV\H\^x= *U it||-Jc+Ꮕ ? Baxk#s5K ] m '%>O0-5NԄLjѝ3Ny%vm[eIk[(pCpUh(2I3Y6TQ|2v$Q|eZu4R/7bF?=1Givں'GN&Ԣ9 \4|!7r535/֦=ߕq nDEM[Wprkud(?ߧ {aMXpO1Wik~rU(M}aM>ݤGSRE ?q jGpv=v`ƹnyv{$2fEU3Bis셙sJ<0BC{Z/[:,=#(J DjVY)L Q̾eMYR3dJ2 X?R[@$Ock&-knp!Ч̜:'-OW8st z9pu292`EA`EF`H$@3}? ގE=kggY$n@:TR$߽œ"#-{&4Q~ʓlsCOzFy&. !R%Jq|_7KsK捉]( rtl0$1on3G o5j6]Nؖs$lW(Jk (PE]qw&ᴺ,U="*޶̨7gU񄍞:Idu_iϹR9}hD9a|#wp='V-N T\O晤ߗ`*@'DpLO6|aXs^F"|RY qG%-RNXA˷:'^>_^@㖍23Y4pvPQV̎jr4+_xL76}m1'q6TD쟃[)cX9o `dWy,ąN:3y,ڦ SSF*2Πu.[//Jtūpؔy 3 }I_^PA|SUvf|{\dB3zޢEwÒڧUwYHM>+4gx.$Y#0ҿv"JO/Bxze Ȑᴢo@>  ;:2 zO_،iRkd)K||l)G}lxdOɽU]>KBKbMx]s5Ro],[kJ~SfxR=D$Q v |Gm^N;>NB)i{|<&9%bm/sO%_`廜gxLq$.վV{M33{_fvy#uy;ft sBA(K_P.pEyIj4D{-C.¨1ޜ1E.j5o}?;:]!?#9F(P`blA/]B&ٳv 1礉j98i]@caVݒr7%M)+Wߧ{Y^x~g"ߎ>TR0?}_8:/ :C<)J"v{?! XM;gR!p#hӍ.N,-jU֟H},<+w 0z,Uo>3"@{k KX\#jRLqT2O_Oʺ6ͅOrYyRT@ 7k/7p+@=AiZ} T/}UhqWAeحqs`GZq(+Zg+BA,>Y~,jI0eP>ܗ(UHf2W\b{E'}e = L+X 莯HP.Z 1eb*$3x~t_ $z`4ro Ś->V8v2lZHGPobEJ Xa2IUu}2(nBh]jنr,yO[U'Z0;nPl)3ocnE./::fԃ}6 z=$.PxH&rDo[ Z~ԑjZBs06I53]zW›iUB?[_ܝ. FLl1yF]&9ik͕^]rWj8ck9kZ٦-6 <)sͭ( ąCex3'<~cΰA z?PI#dCo?kօ#|=J.9P֨F%(K;m* QsːZ<ꚑ(# 7 Gi6s>$ .C9>1OE i {d+F#Q9>5^י؜r|Jɳ S[ 0>'E  P%Qi/@QO4!u ^_,RJa}NznE?kbt}"mI5GNpL:P=&,=pkf!zFRQhZr!VRoC T j'ASG? pFmt;+CGVZ&l\Vh7{/-?n|ok55҃KPhb /Du#pNԞK":rm鑝1Y 2}Ќ,\"  ǃ@Ytȋq\ RzGʱCRĨ+!i)2W ms?5dWNS8jkmC0I;1yrKQ=Q .sF7yM6# r*]|"B4<[2t۝V@#B)+?jUw,ɬn#|N?I{)V#zRZT8?&Y)HbO3j<3_(}mLɻ a{QUxq^d[q~gMo3{ ZjXGNfDaILw@80xğ"#B4[بs[:)Ec"z@vc{T׊] FѕDc4p4⌔aW>^f|8M%@|%FY.9oL< 4%w'r9+4 :Jz$Z9 \KU.^Jr ndWg1|X}ugyc 6Rkڌ ; q š,6Rs K,j3 c?j6J߫ooe&C+ݭ;Szʧ2AmjbNx|(tfeF琙;oHB=7`8Schp<+= 2ClY(mbqȣtO|M 3([Im4&T.y"^4CIU=%DPDXgA#rDf>"=" eI\KIZXcU>;]~m0$4~'b6J~O8iD3^Ak ZI/jsӪk%>%j|- 3,RZh ԭO8IP' Xu-lXw̑TGC 6,3b3e^KkM=J)Bj|Hy xw^_cm1텯`+b׮ʍɫqdL`a-Xa&%/ +L{x+ܚw|8݇[q,{Vo 1!H&ce}+'dY0*p;ƃ(( _Qɦ &w@W|ysͷP.fF}B9q=^HXι:Uї6=d50׌ Q:í2eu;|L¾^!pSn߲:TETvH/Ti.b㚆"0E托6/s*+g9;'Vנ ͧ=bh&x.AN{ Mњyf?t,^h۰XRgtX10,b23&<adhx(FAS^K*PP2=.:޿w];~*6D '&=6w/<yʿI`~))wedfae^GӰ cø>a<1hP9Al6cBz4APIgx,|Pv$"y^/ԇjn%OZE>Ǹ]`t.,$ԵnY,}$e; A9[2q@]b@^#͌\'\iOD W$2įS -BHZB%Mz6)Oyl,M] ;1tdC$h:vsrSVOU7pYs^15wҚ P9-n@c_/*Fm q.鈝):O*PSG0ʫ~HVxȖ3<ܔ$I'ʩjqqZ? z ӉE3fU0OF"8e:qZ+[4lt3 _fe^wxp+>.pCŗr1-r ?dlQDWߟ&_mj4;izomNO!nHziZKeI F :Z"meD11 n_ D,[o}P)cDk y2ډxUf쎌3]Ś'JÏԷ yJXxPh|x-Q"ic:"D*"q"giNAhznrO\ĸ)'2$4oYp8zI*靉]гl=ߍ/ReBֿ)GrK7>HL'mB(4w{צ,l=$?㇮s'ÝSR<2O21-auB2+'"P?,C=H}~r  hXJi54mokϊF6*$2ۮ}4 ׿]3ϓU&Uה_`?uP2҅0K 5t[#/}a 4 ߵmFr[?Z;4mٴGeɖO9Hffy/1=.Qfk)GnvӠ|fuz}[9{]@8(ȓafAWz(gW z m,K=)hUϸg„91FEY߃cu\ǸԎ%6U`BwUlG]+*vFNs?οQ2? 6_ލ~Fh:but[ )?S‰@ʫÙrWijs>1N̓H ZL=7 'b۔qфUU12j|ͻ( . 3L;rw҄Lb7<V'|/%dsx&0kBױ|g׋ UYo˜Jm.XݧI6;B۲U@qKxXmc  ^ǒ;Y> #Xw8e<,O (Vj}^ 8~Kj7X~&x=ut!ƁЮaӍJteU={7՟dmMZK',4w4XmdQ?lfgXwψ@hAtzicgPĞyZ9FQv\]sc!b-L;/%Čv:沎okL_Zι$?nXkUX)K;B?#5R(l}eznklK<V_߲ISO2!.9o-/!Cq*63#kF;B _<\mѯh_Eh tQو|('|HL>dp9>M'EWn/Ъ/g^F} loeLɔAW6Tp5һ)8qF 6Skc"Y[IDf{Pz:i3)@e-&$_(.J#[mVLVpne?eK2@mJnWd[h.5ꕰM5$tЎԎ9]7z"̦L!&xuIUy еΧNԀgKJn5-{EUwyiz'NC׫}4NWF+3GIUy1^^k^@1#  :t=wcJ*9^}p~Cc;Q v$hU.բMX襑gT"2ʛ_AŧA׎=TϖOglxqEA t{B&{"k{nB!0xI&HZDr4%|de.kn$qU)F'LQ.]_H@LT u!~<=N7 ~>qt J!:$t tuGmiw%Qkf0v,UE&|2H\9^  mbAmv&i#i@Զ2~rרd@Éoѝ'ƻQW fe\X ;QKE9bf3 ӽ1C-cHC#RW!)(cvX c@v( ,oٌ`'JEyM-Pں붂AO^V2EEX8W8 { )BոW+A&V`(Zdl*ŀP0Aj}bg zbXe AH&C6-Aw2qt2w:Fs.dԏ_jF3!:qJ"ɖWt8ƣjܜ<4#dZ1c& ySQvz)op)]R:ksfp)H:=&_Q(s iJ) 4B1j=l'ʏ,CCvzc5ĕ> 62Ppan\=ƒ%wSۭdz ͕9K7EDA_ Y#d)eadU-8Hdi^]k0y \>nM}$K\8Az^?yG3֬Rx>Д 1#9|xz?MFhKa] &I}{cW(aiqOX/~8N{e Z$NW:TTߥl.> FkCu"\>`lSz=zL :8 Lp_، ,tĻ"ƴk\hm6&3HG!-=5l}͈Ow:"}]]業FyMg48R)ή|@9 udLћ(ܗE`KT1/ CY%p ̬ Y_T'jҖ1G1"gڌB K5iP@v7Uh'NK76Թ]\QwU*2jMୋ@)2+8~QUKg94d11zp<1E5&䁷y8wDō0겺ڡ.W(a'"MFZ#a-jXk\oZseӡѻ5↗ n8QCm"l$#kZ~M`Eڟ~kփG,.U -eci 8 ^U?ɖp,  s#s #$yA?Z:lrX]H =`iSXCϻk[SO{@XE }Ub`u`bKC2`CMX ~`#B6,öћatJ)EAC\;owR4,L]Y!A>~# .hf9c5"Z5fz%<'I3=^TBͰLV.u&8&jI.cG>=MY;Nb]ht5 ˚ $r4RzoE/^:t éNޫԱ3!c}ypiEIZ9zr )S*\BߔJudʲj dIڤqpjTZ][`ADzUGv5N2?;h0de'=?n5)AHK^  M%ܣM^w>@/2M.uX[P߆@7cŜ>(I_n[79dlY+LrfNL ZBK:o  Fv |"8uitN*?v*f_dcO$QKe*0Js,YK$3ǖЊ ++=]5,9ymX8PGGsW>fM ^ousC9`L;qLĎ=ZۓA'ra/WwC}ʝHgBy(-P\'+ِ|ޝLI[/+:9q5xHH@9+ty FYIt23 BthVB"*@dGl}x Qt}Յ.6 QCp#PjFӪ_QQ]b0`$0е M;-.Ok:g m?w$I)k\Ӛگ IQZ9[W@)0gvy}2~28x2z]]/=\`e^4-lЮt?/ 1|Vl_eM&%K>J/mDO sLiNwO$ $$M̗[UGkaƍc12,+gDŬuh<͋v5rҨ.'8T.Qs+Sƞauh.ˏ!kO|J^ݴ8DjuGO5#+HdyRVa/ M7 }>˘ctYbg3D?Hi7bI)z|_k\üaL,]D))^W@-rBDU[VibZ-Y62h-TQ/ \@Z1$~Ecqx[ZEŜKs[1b5`˝h@ڴI@͞xBQ 9cx7Ōd#]l##@&#a`"7`7K@z%k«do}#Pb W⌴}k!VoxK/1R*& 9q^h@ ZiVave㚴U2c=MF1~STqk\X3FW|rJqeqcԤXwO!L3 2wC>Pp. %9U h3bPV6{%]9Pk !qA\FнkLd=ꄲ#9 fJPDm_*KXSzDhǴhݱ_ZȸM?[^F+`īm3ᮤwAOJN <@p&Hra92xXC` KDO8Ņm $tڕ_F!27TihqqWmJx!59SDƕe M) K wO%pRb$~) F NS%7cᥩ읝֚샡&1r[,jnr9&̆1[ŘhwNN#w𚚰S)^:RN?a`lg$T 1|~hӴ'->:{/Ҩ=VYxD?VʀPWv 6gT7쑭<28i 2uNrF]O;&VbW`knb'8>uσ8{2bx="1ɷ'W ՜Qywh ͇Bl$}Y3f r@&6[&_Vq31HRrS-~[ٛ,Օ SHې6ƃn >ӜW{h%NBAȽ RL(`B;Eũ '9s7zǞ'6=*o#Ϗýx7rQ,cwk8Xs|`SiNmAJLȸg`@2ňI `Q6wZD(zhpRꗞG&>}Zqȭ;K ^? +^vH )Aqj'e.}3;_m$ vjoKu֥ӗuENS_Ά#j8AʝM:"ҍ<8hxd.0_ hp(b/u~#Գc'=mB:)/7TJͱ)rwC=ՠ8A}a 4U,sD90*r:i[k-+Z2_v(cc yŔHLcZ#[|%F؁R㭊0j{RT2+eA"ff+~S^XR7+R6h]ZOc*6ӿcI&8LCZn:p<}YRJ v ߎ:yW>Tcq$@}/^l-% D GΩkɠ ltm YF]r)&]=lk 4iK\1-b>xp6Z$+ 5wݕݼ{4İGo9H`m~ݚxvcKtt=tpw[f>BT loNE֥:P0Ta^gIktNIBl1eơݓC?GU[?omH`?J 7Q O:nfُƕ/Z;0,)o9gE:JjR~Ir;pYk;@4, N39!꨼?/'fUǰf@r;/,!`^SøgvSxT b1巍\$|j9NCmep¶uZ'!# Z.-i^Ds$2 uApM_#X_H!e>DC15/RRy|.6]xD{e>*)T|:¨k /U4y>`%kXFl  a̴*=\f/Qs]IqYRߢ "j&@)mf 98F'ԃ񠕊`o#ОS ɐɝ0M@ӊbܖlDUM(yDK.L[0`Wi\H6CϢAG(<>#6!w׷Cg#ΌS⮐[fnh8oi?|~F%/R'gtDM|$W2ܩ/S,US0b)u\?$½qCa؃0$^\0=;p~?V"Od&o;3VgAC3bOhS8&+0zky!9f%LSAwl3EyhNGd6nU*^^q(%\'Jr=, EQi xb@IrX&̪|v]} Wno*G>hE>$gwo$ 'gFn[c}YV w-[l U[ÀJ셉 w&/wqI4P@ mW"сyDs޻7rtԟMW^jȯ*/(3;dCW y]Z\#absw,Yc_+bԇMD4{k6 aSm~siDV$/$ۀA:A9.M\5*s1J Djj^K&svg>h Pb˒x',XRUIC^7U>z1Q{ZvQ3b -ZO$qJPy/Q .oU S-1 TۥؙWIrf@|(٤]=ň蠵SIq۔ʨ0 #F8Zѿm, G2* S͙c*3a.sc=.5A9g&vد6zЌi &.3*NnFTI85rlG倗?lmfZ ZBh* nxTw@19%+x8Z5v1PYeKVlIlpKH~ZAt5Zu,Adn[(S ~ͥ*xnhD1y4u"2 0,hξ( v`aZZ;g,gQU!J{a8OY_\ +f.%i}ֻ4r-*:g$V]zץTț ň Pl0O&-]P-$ZdzP$ݩH<3뼝 _Iвib.1@QЎ$mқ>ZMVzR#6 QyrI׽w\"I6=fniiIwU{ձTq?R4u nEБk0 46l+]/b<^ٰ7GK|(FX/ۤ)4C3o0+Gv՝=B] Y^#gq!x HNG9L ãD}_1E:KU\#ˈ&Y$9=̻.GE+H$+! 3+G#̫; ,]|羀#^Y5mZu>)fue,meHMi[h/s?ʻT]Hԁq}R{=_49¹,<=A 9Gwkb4z}Bl%&uۃZ(`)1XQ@zozŒռ NQ#IJXE758 Ǻ́4*.24x%B4*AZDs!Ba@ȋޠFxmuX-yJslb)r۱u\v9iAʨ8Q`ExI>݇/ GG猴n3GluprШZ2?۪*bgP%DpK6p &{YJ'^āfdl?2kqHb\t/D1}BصB^eK՛I͈FY=*QMu)$wk]ũt\A#W./ $dޔu:wZ%C?҇Z#-AUё ،r%U>)G60o|cVgn&i  ="FZ{i}>k=qZaxZjU(RKxMd=:r㐏)R( q?'z;^HN' WrJ%f*# x1KS5@N]zк e28 3 L/":TeCe"o,%38.S=n^kLC;MfRt$R&07$;#]  Mo@f|MUm'S.D~"KEeI҂<r.!ؐ`+@[^VitHa ]H S_.,AI^Uz E`+'r9բ/1 >gToKO{BrQwX~Rp .z?G4ݏ<^@f-@p{.[bE_ֵ֦zH0!VtP24|85Ƴq=h js>wVkA>:C,KX_. e0k=R44mXxH˱Q{:|>s =Nƕ|59ouSnaڠ(s̡](ޭO 5@p!ή.^&$!!' i..%g@~NPP׷ <Ai"P;Kyu19gBQ]3x"FdƋ[i6GVIঢŒ, zy0ؐ^CXZqD:0Bc.%b_)?x /G?*>\!%-H_aZBp/#F+O|n14(A^bLbѭ@\\xubyLE*guoTY@yt( Jf?!Kvt0/fk3Jp[G$g\FE g%8bݴqX%\7^GeVwfҲTѷ\=HT߾'[!`7%ggP҆%793-THs6zۮ1[G/M5{[6հI{cbDҚR̪[.f(H|{rʮ͏/ߗt'w T!$"lcGNGڋ n$62GXcaC.?@;PЀ \7#0la3 nGLRy  `B|n 5?E ch^JgT%'ַ# Ug P B_iw8U~,<`9Gp*"SL }XQO:Gżk&v)[ S"W/_-0)`SH~i|]~ "U 8͂؂s* UY'ԙh|;I&Ew?yxÃ"LX+%w=Q,UyIC+բJ4`'E߈ ~ S]10U.ҼokkPv./#'fo4*xVojט#' (vhL<4̴ 0 4zUO(4 -3]]?o\g9%-e8^K <ٔ3&)wl".79(!"ű`17ҴEiCt' YWS8iμtr=gɧ'8vp콑<5ʲ~ 5EXx7tI;Z>U*םo@o"w_;$kRjͷ32Tw`"r8yG7=A. jF;`7j_ %!2PҤ=oi6}cK[t-:sG1-Ki [ܽןXwjTiNLIΈN9|K=.ŗTj4b}KO0IYKmU3'xRMfh1$fsg}H긛uZg9r01+g:%z١`Q ܂\疦c]Y<3+E~Urfes零{@({#vvPDhVXtI7g-,?cʆ'OHȬ 9eq7_ m& 8Iչ|m͉UE^D{cb+ʾ#n}:I }:ɰVIѫ6 xr}ZVN˯n ۗDnnWAXSsmkz[KGҩ\|OsR) {[ Tӗ:CD ݣz4ho݅COv=F5$Tq4?D~spi<{y[~ JD;%U!osPT;ܞ 'f&&DDb%X9{|?2q %ۨO6Xɚ%hnͣ)irPkTmL|Y-(n?223P/1k4V3y89f˞`>威p{e*U[8ZRӝsXc J=F/[S\YIsPai 5>9Ndz)&)v1CA|'9<I3h=@K0\Tޏ]#Y˘0Chs{MF ;lSUݷ usn˅..! EvF/1fפ9gC~3f?R<(E ;&L\ ې@OFv-j1uJa*GuI(u]z#Ҁ'1tp5.WJx?H4w\V҄䅿rOr@ȉ]2ޤ"r{;eĐ1/"TֶcЏAȣWS;lَ M*zRR:%RɆ LHCBcB.)~[R11a\FOe餳[1xg 7~cD+xWY4#,ƚ}'.U5V/f5J9M-RkrHwJ7J3c*tGA33L}5Y/leO}+?i@ Y?m,%ξ*'| z)j9?Mx\;*ƒԫ0m%޵=_Z4>MgߩO='_e=!\th[Н+{7~ePU,@.~ҵoWT!dz sMPMg;`snJ죍tY^㊚P-?C^B }m}Dӗew n뺲ڒ}&Z̎{vR(֩d9D / XRɖ ^ΐ:N "6&"R"W]B7AlK}^Ie꣊3\+QȄ),1 ׀Q۹c$GOr%-zzqnkb7-ٙNNi$"+ZWb{WoA[я[%aVvLa$d.U#HI@It@#+m,A"zeWW]opyk4RPy;#prXR1 F8)L3s3LUE/!:?5'Bp >EOwXXOPGEOCSg0ۍbo܁îXkӖ;7u &bGi=xEd9[]K@wL`P}Vy"oeZ5SX yiDsЮ@>Gyhصs"dw {gi@VY~Sb ыr$&VFQ|@e)ıi?rܒ/tx #46,FP|x곝)ˡzWF7]%!s%{Sǐl%oЫBٗl# MPBj#`M-4p8ѯ c3˒Cto" kI*D9-mQrr>/|q-/e% T$LGkν:̂TŒyCG>BOpͪ*'XFx⿹Sw1vK@2d @mEы%:āycuY.5notm+72zMGid۞' *Io**_+f^O Tn]?KTВ/ cYꩡdtu):<^nU\ORR=)Mp9Wi&fXMv׶Ϝ4E Vk569]K-RYWo񤿩:8~d'3(;D}݀~[IEΩ $%]5OtR"uk#mAZٽ@3em#W@h2pq+8]u˕O~xbGyWtY7v!J\捃!b}r*2F~|O,- <鶽ʛ cq0S[)w7 L`4,/$A#$ՙ!LSi緶]ux=eKcڵm'F 425ޙlObzx7,'sHBSc\Ȼ+7t@,|s!+ :Gxe]/ĮQd~$j_L7Z}S5x>^)zC~1Y׮(܊܄ly̼NjlȹјHءbخ m[2J~GXЭNerjG#*c`^a<#Ścswo(?!p.Dea+m_<,!{ @$'8imPOhbtwrv$s]೹XB)a ~n@8l]&ޡl.#[y WOjII^t]Jf]b/Q0W'kt$ۤ+Gt1 ".vfa 9L37/iB-9gTjrc!v562E2 Z`/WYD`Rb,ٌH_E OZ&Ӈ7Tf l8ڲ\K ʩM -Mu mxӆo8%f8HF| myc*\_evpa 7('RXI7Stɀ uhzu`,&i~^T.z_8&V-b۳) |v.jԘ_*t6=^@)y՜STՔswQJ0MJbLq0֊:aӯ/Vy~pQT'C}v ;ry~,`2UI`sW$EAwAU]]Oa<j YD=*Q{?:d S'j7v Yrrq~Y"# @D?e+.:ă#K&{)d@K?1F͘BԗIէ'&̒c ߥ bE)YV'I?_:xf1ϟ"L̬g:A?@ɬ ;KDfi7m`!2:(hAIhhAŇ} +3~jFny)ԤlGD;ZU1 ~ MX؏ }dAμIFWk9i;F[K`Bu=9ףߤ2i\ADZO`X0})ddܷV{sRV_k[}jYp<{%hv+gap)SV^4 Q'5YNAc8T)97V`{iWAɯ쮵 p3"'/C/vZPe%rX\+GY(YgS4ɩVTk=hLX=DEo"IwRb.y[#C_~x\eGɹH fNU[R;u՞s`eh 8x0 ieكj;$ؤQy6#GxS`nOc| sXjHp>>{aFafmjUn5s;,2١ vOĊ+cJVz+OnE(l/{Wn}ȲMዦ3m5 )ma؎}3eZ6O# 3,( :;0 P~v)a@ryPoެe&R?AΛ4+IyMDn~@?a)^ig/k'C~G.k*ߨdĄ`±*哫3i^ph}V*~+~ %U^>< *Ƙ<,r(c鯔pfh'cT;DP~i.O/LiMDS̛b%"龲fDƹbտ&nn}ʊS hEÆfTǮJ_fzoQ=x[B T3 hn=us+d"SɼRiг ^}~2 _7#͔e*l'~ӛ1^ ;sy#?P=sͻ'7f#pSE͘I6ē XfT]]" j4@1ɾ2x^P^)b6e6fz`ΰS*FRh 3ebXcs)[5~&FX_eԥiSv -lmfT3YH)V. o ^e%]r^842n%1'4%IoЅ1ٚƲĞg5g UeZj"1Fxaf>@(Nm!tsq!HblP;Ӻ D> ȸI'-Fdbm2 qRD9 W=pg&&f!&"ѓRj?%afk" 43KT1Q J% iz^}LC\ek(;- >B*|beM^ZВMSwO Z9Ӗt9?M@A~a-O\L~I]`>PlR`Avtpg:w TW;٧Pli3A-R㙺:'mU=*fpWŸ#]_%9-ZU{qoLiT!W?׈YeGq9BSsWOlW;W*쎚xWg(3Yɋ:ɵeu#ån[t5X4s\o #A]c p+[gٓ_ժ9ؒwCu΂N0|؎=.;XI3V\W\z8d>:Ӎm$ych! 0nG##{Lk548 JSETC!)avB%M|]tn3E"̣6%cV82z0 Vs=sY,ZX]ũ-iDwtskcnF)@ %M;f֬axf`64(P.V .O[ќފOhUײBS&YbZ|$)_>ǩJ5fm0TMze"GWAJqlXkhU?|l$E#R{1ǹ4xK}IVP풻r*~1Jn';FK@́zp?"A13:߬R߇UjP@W(eZ`5VR=ymcmbJvSپ ;UZd:,6-!o'1xreN]"giZ'3C^>nUݍ!_aߊxwc/-:F4A3:4FSz03V~M-ހ)%z €ق|wtRuDqN㓼͕:cu󿵥i݀pj˿%?RE>`Yྨ#;{Ϫ#VN :EkZ?LHj H9?;D]\ 0 82I7$6o8U`׃W+=6AQ[Mu'@K^pϜohhš1@Wfmi`YI'X&b #U^Y1*)J>'=Xeۯ |h+ ZӐi&{ 1}^Q }a6Qbv^ǰ'_岙Z\CRgG oCi!?LIGz#VphUG /hyoa?LQ&FtA ~,@L4(4QZГʢ* bnڮeH "`Omy1Czѯ] 0A3 a{ {bP{@ܕDcj*9Q 4邂-v%)9G& h%. SSPۑHc*+|)lqaAql+|x(ɕLG~$}>@od7Mݓ^&3y 9Ti:V?z8~|;S J.sogGa32 MG!x)(6,ؚ>hH=B6Ü@~ {hm0rLڥ' ! &">y JI/#^qtίMXdm.C1Oqsrӻ2< KGtPIN-j]Z!^wtr' דWqs ʧF*VU"rd:GШs R1ad8i;ət"`6rhUk 5FgbF9MAkUTk)\?F[jNjzUa3q`2b5 I 虊џsav ZYSA!Flࡤukbýwu$uh=OPcz*Ldw^6$!&oDvc7.2 ӝӨM8U{&i%HPT#vuy;off.B&>˺(VQ`#-|ӗC.- [TʛYƔޤv]vE==㦖ڬ;Qt)^A4 Tm7i1ȋ J̖3Ų)`WSI6Nޅ W]B>@mMZtʐ㕊wxyr2^4IwNOu=NM iMkıp7 T?<uV@fb3MfQ,2FfĒQɝTPa~qRmae[.48n0[:9a2D?Irs~40X\$(1/PWOX 3Oe]a l 7&7f9*^9rF[& >t R $48ך4GfOsm <*Ua(O:Za'M˅YyEF[ߊiWS![~Ulr;KPLp Wh7!]} nN/" C)r͏H;Z_R PE*_G0'@@OfX}X5"T" ]ﳢ40T.\C8~_8v5 n:G"E*ϙ^do\ld4]]ޔ4omמI2js" ^%\wO]R1 2fԱ,Ɔ>amcOn~krhh<4RxT#4V2 vWvz>(_k42U5ΌgG4ͥ3z;ƍeHGL~k2u\ALSyd}j#9pFk3QbD-+O >ag8CSC6jRK^() hPC"q0B@%[*?(HOpGCbVmO/\^ ~.#eJcv.شz NOu!WJ8+sZ{);a;TEoޜ$/N&í:'R5<|:G=v &BYŢX4<@dpO`e2UP.9YYBqS^(?'{/+^E.K"r=?HI8f2 `X6Y @}c!yr1x{ ),V^.mI<-]J;bEȻ#0)3[4j ])cSb-ZPX?B#IE#Ē!,5[Rc7Ζy[Y .)Qzʷ$\I&6ʖAo|'_(KAXh`cTS_kGW%+I Xܨ.si] 7tXs2싘;B6@{t'n4.cbE0Jڤ ˾;b3,T&{_9 `|urXOV4-YOBjh rf9 ˇi߷`p"Jv-%ɔ8YSw~5$yͻ7Ix% iok`֛;< ތ-LdI&FHPTD!߉Vqd'8.5'UAG𦶗/qoF+E4O Iw 8U|F\CHģ܇M(lIT>r}C;r." -,KX ANXn 8R(17ޖS ;'D`͟rp?éWdwfA]; ^Zg(+h:1˨iH43cfpv1d;g_2~Y$̗k<ŭOb@1{zTQKⵓSS|M֘I?1"x2CLU.i# T 4 $)ca9ZoGXtZ!~khmC$M:ejB茢_H <[rK,}oM֤!oS0Yq~ni1,BKq{$;n UKFQ䐉nw6\<\F 2 ,|*pp~ S] 8YEFU Ye0GX{D3"wl6.Ek4IƟK1c$97ïzb ~ e܌lD+BwRԘqJ(=~ # *1 -"4A%RI}󉞣&& *XR`_+1R9ay:~E1cg*TɌ0f;&91k1m ,ATU'L[BO8ƀ n|&E+;4.˗ aXXZT 鄟3i_T9!P-㯼5Wad`jAoϛeR.ӧ-}^]rqP^ke rcM4 [!"<D+&!sNA%-X -Z8;FY卖\G~𮟮4l I{QQsjꓵBn5 l.OOiە=94׼*:&>ڥERAzi,iL'|| Wj F|F5A7;vRje`;uҎ ,d~ )WCz?]+N {5xc,0lks-/IG//e!9a^#y/vJEQhg~x./Z xP~)*REkoB&ay2Z`K0$h]`܀:ۅ=ްXQQ8}2W=*v1AAԞ]@Vd-vٔնOލX@0D[bR637F,f=Vp_%TiQ =E/Ѽ)ʣ(q,-L/x]{Q^oX,״^9^ Tb!>t-^`I%oa57-2«x*zKq f/8*|FC BTh E$绍~tњ^8eM\rk6ZEEN#-pn]"IU͐;+cbWIR%#uP)Yhpac-h.1*p!c1ɰ8lP V55Mmp@+=em_&36+6e`ShxkY0t$/خ <;#̃iNW{ߖvXs=438FҗX(HX>v̬i&79NW8Wׇcs4A6=MjӞQEx e%~To Jͱ?>CKMH0mN)n ѵ%k+@Fyi`j#(Z#|Ӣ[iE4kvG(uc_}:ʤ> BGst32G2A<:m0*Vϥ~/s('`D_oa'gd3 q=y[x`4Nڰt[ Rg_OUuɟNC!ԓ&:'&?|M )NDRE+`Vp3Ќ^U8>HBy|]y3c-S/9"JX51?X@4D;9ivBf~f"w "~347o_sAy(M0 |-EAuE HAsP'QéZ$&1ZK5iºWدq{Hsÿ#s+vL2.16?fAՌn(KÛ W9q ,nH!ZRp5ul6\MDMyVJ>~h5H)T./Q;!" >>IYQʨࡳWr:*wcwdC2V9x zeDm[&M}kHs9\oUvi B&vi p:y7O g; l~ K(GMr;bWr[ Љ[yHu2 \r }oSaG9~:8ϲ>Հb֚-"_>迮F\] { f?qPe7/J$d:jӭ[>pVw3"Yؒnv[R$ysR&@yP?>Y5P"CeyF`Agy%81ZpA0Y__ie"8^g ːjslHi%@ļ^./Iaj?kO՘/b/#L~z _KKs#D`R/3 tb{bUH7tj9)D; ̻ H`O/]51#,iqRVx#w:HW*ZE%K%?{j{؍"PP1nLu-.!0@0ܔ-egU *-TI 4 _4Z`:@k5XLm}W:J%O;T}L= @uH.knp.kãXJr&4H~De=mc(]M;͠*&8 ņ ?_͸\{!_6{{,i2_mA;eM( z@CUX/XkBt?DU_*Q4,+ x `i'n]\z\^7N*Jm $} b> D̮XZ1$ά.aI5dزyΔulaB"bxc{zg4_[u78JtE[.dU19=ỗMV?/*dY0N{AuT!өZqNX\oQ#dMvi`Hܓל 9r.M;/әpwӱ}㳨)63DG:7E@ Hm &/J=`/bcU8cq= cKIDnm+{1/"hsQe-DU~Q@}UH.oe:sa'vzpaU,}cxyhc\LH!o0!qhKRyZ芛QvBWmجk,k)Sč#%\IBf*āV10^Dϊa¿T\ēo*oWO gT|"匦xbm%詁-"5/R2oG{.URp^g̞&i{1}Dm}ٯUC+>P,§G+#7qjTkl6BCe lw7E[qס6q$+>6lc"Tp)e /m) AϘڢ 2"Xsߕ`FmMvK zXEZOH &ݘ9^bCCvHܱ_,!' Q3J W݉@4Q!Eiuc BQF,VL"w3,.m{Qd](| q5%ipV^IG:%)#Կ{ɘ]UbqVdF$@Gtkpx`Rݣہ[gϺ3k ɘBM !Eb_`PXJI ҄f:qJ-T[; >iy9ce%.,.4c d H|Z㿥s7r¨x;6zI6^AWܙhig^MEIÑZSC!QOOH"V+<9#<=ˠA9d2Vuf_sl^z56@oۅKQ -d`k1BUrkehu|zjiQZȷa+h{9 E;-^wρ-n’g&{$qycw56VDg7{|y@ M6{"{8 ԴQ^?7ph mJA5Fu}S)ltpjzMr9r0ԓK[?s nqȼaGƃLcWDAH,^)Ğ8Xנ0VH2a5%|ʹDfnqßgZNPu- rࡅgk~ϧhAvîf_e<~1Ub /(w)] D;6]k<ʫvYS3aI~}|yk,z/ANn:l#VԷ - G.ٺmFWkɛ%vXrfCl_ ֐X"qXޓY$)M:G˴ Hgu8qU lrH,! Em`({hrPxFc}:~2&yHJSϚ, L m/[8.꣄QN$ٟOG}aT{SqnI_ZZlK2LX`㿍+űO2S3YbC q[gu | H;deʢMAl)s2x)l=-sK.o.P>Ȓ7{"P82S G4drQi4*buVl#OP,. ȯp훍 wr IK UGz,TX-/R92 ɉVGF*oe´Þ3k&AAWryR_9-ʤ %  $15wSEcR i ~#" sϏnΑPCۮqٓ;*{pjqWs?hꧾM3q$w WKbk:IkfhaO}1Y]us1Z:YauT"ydcHAY] qM%YBN%8RA/7ۯM?ǫ%L< +wuÊOi&V^ Tw>G(]']b) DN:߰NS1#x6]ȾpA!}zN\0CA:97df$;V8*hB!0wbGgXuXVK9Ɂ%uiTM}/]p)aw y-%:i~DfTB9yyA(pЃؒDRQ6`Vbj^%NzMA0. {' #)ҩ8nINŭD?޶.WNY8k%PT}o!$ѩ~l&|+\c=x%Sv؁L'm}my=zUiq.뜷`y}J[J-tN⚋ F=ʰiUCYκnlxЕdN ݬ֖d2X{\zl-9n\ܦΔ MtpX$Cxi, Y)7 *#@ײ}c.\t!hg=>FB'ϰ_궝GHnfZsZm;`dF@6^ҍ%~|2gs,|ʔG)8[1  fE$Xĭ(g~Ym){EBwsRJg3Kk_ZCǀH:Dǡ+Upk+B):^]o@j&tٙ jbS (E_cM\ө<Wn>xwFrYƭHCIShZR+(1*+i[G#u`?ǗpD$Nam"پdRWP~[S;~[A: EY<4jŒ>a~D4UU'x$ 1}qJfݦƂyJn}yOd"J|bb܊}!4,-A.=gE뢤,@j2ZϠ(!~E#!?umբ_^|^> F 1[Z .@M#sc$8hǬY%7lDvu˿>GMaS9\# =dw_l{7cƽie7iM5ЧsͰTdžTg 7f\l -@aHwc)hUp6MRM~ۋ0cww$KP5[tl#o4PHKB Vg`<0T}zr4ju} a_2م% Fu4{R|G,X53U̎`,x%{*3^ z=0N6jy< e.U|GBee¸PwOUN"27]r}3@%2 dMӰ >/́cx=R2p$BBߙ$%[h:nA1V6t= 5^ۘ천]EDњELe-HJfb@\!ߝ 8j=yn@l4SG)VF8-28;۱(,ƈfM՗(PG\ЙS1ݽ +6m\GSуWxͭg9ԋk%U:C .2Jwy&MTN1Đ $8x d : Rl{ B`R $Q~@^0q392e/D@TkS;ANED#Xam bdOL%t*/b7dP/uV$F9ڑ\ R۩tE`,tk_)t]nxbq]ιF=Aȫ}-,EzGƿ}/4TBG>x LɁR, orUMJFna m:u\ M>o(ja5H>Twfz( 'ԟ-&{Ic1Fi.)+ORDhkM&.zRn3|M4痵#_AF-L`_rY035 wE\8fUnHc јyPл߫|Wwvڪʉc%ELsHoaoM,i1񤄲P!¾sӽ}gu/c-R2F3h0o2YI`ON0lɷyy J dRSn6/}Pe0!.q;Vo<͓`J8~}ʿV6elZz/tL=BS9ضNB0pʾVoG&kqb 9PWAl6~&_ljK?5 cuvy!ƣ#^ h_K5>=>%^a.Мv[ݝ|QS>\cqf7 恡K #ңB0 ,B2`nm V 33f( kq.'#^-+Qy?h+o^\o!ьgVx~h}s(w.f?d5;`IA6Xw"BS~[b~n"! ZߥOg_2~eіõn=qSn:20d蒐z2yZ)eܞݠiD7 1SE16^ S?tR #֒m7Qxl|7ON6ֵ3yW(n++)Č mzO_~rRޮ9X:t"Dqipd(@>,勒[bVOv*u /nBl*DŽbF-L (+ s.c}s<S2Tг,L.@q #rhwxq܊tD8pyQ+X{sli$~<-Z.c(˷%S/ɶHB2(X7?;ݴ-fMlPZqgU)Y/|7[E7F^T^G Y y.P/?"<1=)+V=̣1 !HpcCgI!!7ud(ΪtϚM,ggWÐ{niX T@&pw1v1Ewa6D[w%]aDF|7РZ1#WV7ԭqA!:x e\u˿-}!H!͢3%\meg%,No“V`WKԢ+V9g?Xl u(6M-%/R~L{w$H`'&:VǥG^5(cpXԴ'1Zq6Wտo˜^^;@<=@TaU(2*iԡ mUIRBFXv^NIIs|, AD rгL  [mydmA(8a}Tԏި%|3PX֖GGkaNrXsYIG 26o ReNj"ԛCCj 琡)*L&|'q=[\⠐-ԛC {oKh4WI2 .mw4 R'q4I4 G(T֜,nԲ5'F&V'lbS"H…UvB͛kTd>u6xHi/#}{LwHڷYw"aڬZZ:#{A ae 򱘿}t̊|_ϽX)v[=ku!8 Lط3ۏ9m=bλCG&E3gOv DdP3m9_Wy5#<㌱:n=dgio~UB:G~yXKhɦv7mk۱_{ pFDћ`qz߯94(d6&^4*1JU{ %Bg؊"I ܑNזGf+N*U"@2S S.[6YoM3ktX1K'?io{[&M)B)6pA%|/ c ©T&C nvlZ*= \II#-Tmž+)#6RXn^LQ%P7h!A0O:HQ Q &6bDN4DArXz趎YXаπtTW|~~nafz>;#1oVY0|Vq&m! tP_oͨ `(߅e [Jz(''1͘߼ڍ|| vxP(+CeIJ9eop=W1M}@:By:NDo,KI[LG[!#ِ ~>4PgCrZ it%ukξ7В ug|A"%_5On}q)UC9ŸiCc\f3K4~xs򖕡byTgRCKyŃd[7ܬawd7Nޔ/casPp&0J ZI,I\lѭ?WYcU?Pj?Ǡ徹!Tauj#d΍Ikx|b-ŵ<tE_mr~˾rϴ4|u%7l[ Q!SSݤj!_Bxoo F˰pM I8J4܅o$<{ʋ;&EW D2m4t<L)$>N sxm_rVYԺ`'^ @uk&6™l a6V/JĮin ^-tcAWit~ [j?{MTF{Z" -MrcCxY2*db]0ڔl;b]F~?t4-m@/0v#/1e12ߧhYeS()N!BjZ uRUC9ɐ YcHH:|&qרG"XB$d_|@7UOYl`b>8F۫T:N kMkC粥 G^YT[[~sc\ 8pXLPMx0/4us*xXdLq`؞l T~y&ntu| B'%D|z:%x.0!)V<;=-&ymכEi>9FPb pય#p.\9ͥ-tI?=bbI?eo -S߻Pի@)Ar۵ĂoͩQp#C裝lFS_ހlhDcBfFJ{ם$hR ?\Vo9AfJV[׃rO@@<>&!TxH=Rb37f!8Ŋth 1F S}4k! r`s~?fpij}yfI*`>i߽|dy{45ZBbp!@at0!Ļ*WSd Ouı;R ;:5b✉Ny8͠fzy!΁غ6&ޱMhO!`=fDڨP}[b.R6 i@rSmnل id V陝ÆX[|Bz6in,H3n0BA4lwrdٓ\vϪkF\n&ہoB+okV.(UDI‡vI^Q6vT2No7p6xB}7 hiYȠx#Dg1M4j]pr]V s%> Їbp/#F2zBE·nr"^l,TE$X-c,dէ}Xz=peSǜvȴқƊuE x@7'ctA%xΚC!BL^YBӲ}2Os]M3+tО!7U0OM:M-,g`i]7MLA9-Wۃ?(An+j nuTx<Ϯ)H{0F!ZƮV%M |O-J1/ 0Ty~\gJlI"Xjnǔj-9ƻ/TMzEg{u\kx"ť=c&VViAg5B݅h}0V JSPZ̃3/m4ާ ZlY/)[vn"Lt. 9' "~D0?YWk4@Q(\ػ{׮nUH-m ~џ:^Cpaͪs нbkI'A+|Ejm/8d^3VPQ{v/G(O MLHi 3KV5օc&~TR b "A(*4oś *SW {j5`ŋڲ/8ʓqj^䞗 O5tډv\EG'=ҡ,aB@6<^#D5vC4z݋O^~uC/"T }6̠\N2 aؓXsE){HjC]m0Z-/Pq8g1g ACSGMhm{Q~/ Vɾ ?W0wbTԨͪjpOJM~A( b|ᮾ MCRU_`P̟жָpY^(qɝe su &:go-Uq;7 Om H;/fTifxt1Lv#]m$:=OnGՁ?ap=)L@I&~'VE8U@nnB7U> h]I!)(1\ĭK{ DɄ< ƭDP+ovݰAw. 4<$;XvγqyJAh(\XUi5JK2'=}U | 򅢎Ga  ֛ {K0k1̐bx/<2e?O`ndMo6^k2a4RXj(MՓ}c T%Y}%)"kiB0jGj!H?l}R6%ȵߘB>?'GJaԁ67,zK&fʆY|P!x{2?P -g/g``Ϳ;eSBX ~b yWjKHеZ{u,NXZerwObQ#Q䝱!/Tmyƿ 9FWRt +*+7K9 vbS[1HpsF""HHi]r,9U j̽@T7jNb2}VU2/krG){PvM߮Yԍb)_hȤ)LLվEp &gʞ V4^noܾ6nfR(|͇ oi? \-J^c*]MYv#,.>^ǿMr: rprv,()2WTL^P̝W%O ֛˱;[Hd8;pE`#g0h@j,3lv-KpsB''Ƴ¤ޗ]wr=@K[y0~:#d[ES0@׶{UӀї=I,<\=zݦ`ec" >vIc̙('5ळG;-尘BOBi5 `lAL7@J+'wVK½W@0xӐM|ill6uH&yS!ئpϩչ sh&R>W%O$6@V?/2kucܯ[ ?_0Q'|X)̈́4G;mlV*q_3 96qAct0w܏h*uvgAc7;7,z|m ?V˼DBbäPubKL;FmRʨ/AM/PAnP z?Jn*#eWlXl'fУ x/cg҅b-Pnr3ȫP)3; ])J|tC,Lيө \`ݓV!;l_ sއ{z(q^i@azm?$ˍgNDiD-7OT!xKdRyRV[%6M-,'yOm#ɛ!=;zJfƵZ+P3Ty1iwûĴd3a8ܳa;*g#BUČ `XgR-'Bt5Kz V$Y``') 4>lF\_eeA>\ Im4笚30^*! $ F$`eRpF@UQ;\ }Մ3v FjL\HnJt&l-CSֺ>Jbjg@Z"w1mm4%2e62$}|ff:2DSZ,<+7`Ɨh.{B_x+A ijLQU/dK9ƈn - )1>PbD7QelPkD1.!ԯdd$|8Z\CM{?漡QM^y{M)$ZZd".wC t@-!)Zw2P"Uט?'E|qq]n+,@t(MdsymKCڎXFW 4&ޱVfqWT!l;(x;ԀvY^lՓnT`kGALNz"єY7\KY? b  !o0_D:aP +y10Ԙ 95 c]lF~eEbR3 0~E}T:jQJ l4Rs6jKlzX.D5ȅy=ZɎ_*EQM;L =L:@9Zg-Ћ0&qϠc/(|]0`Q4+1A#}i0} #N2R"%cn:Cl5gJA޼g)YB.xdFL؅lJ\7Rcӈ-D޷cV@ qnEy;$iSe r# ;ؗs?8<'Bгؔʼ5{ +c>*}O3Q+8e49U_/P$>nug H%b'O nuE"@Ch)Өs85,ŜJΘٜkE-%/[ v~ϪZ: :wkgA;rJPf> ʼndKjT YGG{q#~(lDIDVqfht. p[SjǒN=(*vL*g]ICp7* Mn-ïj+*2pτ[s2z{yHKr^"wp22f߁u.KiiV{6s8P7X7\[ ^3͕1 @ӳݸw[ۣR!j{>1C xod@/5%{Ρ>g4aۮ/vzFEf,E49D9ʇ% p)/Ŀq84bV@j7#~0qDldiP6'_'LDNb@`=K95ۖ6c<( r>2y4c^ 90 baA1{wMnn< Ă "5P`Ũ%\fX4C)U(PDrwߝ)ܓgrk`YxǸ+O>K]/'5O]>kWo+r2dOɐOIQsi|fTQK)\ N$ W믝pr TUֻyԎVtРz)NuM}e_3V{I>1>xX& (k]ZsYH) SN4_Ά)N҈[bܮn@Y*0ҰDkuX|gVv7:H0f#2jXۆT2 H~C@K|!'&u-}| <߱]|^9{-Bi[0MHGϖ8h s:v F.Qdh&\-'284VN[siv20{ڏxWAr@ rb|&B@ے [:&qd8u(U2N0[Gzz( \}zϚ0)xLԈ7qOGnm.XLcG4oȠϗb%DWou\=g|%Y;xqh4e>H A: RjV[!$Sߟ maNڜ+?pק~'8鍘.`i=dDQJ5\4W gљecAtGС nƟV+o;S͇FMZoQ[cu- dkZ%=' ʈ -cԿSj1=//ZH[? Y=YL\N8I|{̺u( ~WB42) *,;ynx֎Q^ى3Yӭ; =SMQAO4F|:<^~ؚ%z `Y#]gk|y`(O݁EV?p~[o4 G<*C tx[=^KFL~w SzD(>G ^z~fuٍ#VҟOQL0"RgvO b55?KyǤ8ǐɏΎǗ=M)W#aߙJN!;[ɑ02<ʑzHibׁg+lwgwGapPwlw2o)i|j}ItӪ Iu.d~ #|]k \aKk};oaQD7`\R-ĨRՈ{k&[R8Vxj"o ۍUU29ͪwf("8}cvH3./=ڲs!7T ^>조䞦 pTP|H3`@aҕFbnr6|q6ct&ERYCjLm~FA2ªǐN'K?!%Pcbz.j٪*&4[uoH.|,3q$BFp{jRx'gH}IR ұe]0N&ŪbidReJ(mS';İgkG{̂V۶eݏph~_B@*JC`f͹k^ %U\QɴV׶YiY1tw=#CizȁGi' Ҽ먔[vj?3fh˗-σ\A v ̙2߆ro).>/]eOp+ƞtG9v ~}BDx*Di|/)fA>"N@o@B!auK)AU/t [ɏ˒?;50ێ~[* QH/KM BPp֔r#]mF&ίG_0ja$/GD\pHJ oa ori75{h$/2{ $I0{'Xdi$~ WjW98w* -j"hEN9R]!!kNI ؍!ɦ!sWi,O'lLlj ƀndZ!r*!eL_9MH aY7uH\)]q(- W^Jk^rn d4dB>FgfVe:BQq9:jgZA>=jS1 Dl-;Y@mU^[{s)JƒWԔM[yiT xtoR)l?j5uR16lD!x1thi)\)I;8RB!K>`?u:lOiP廍,R/@ `8UBb& @ ldV6rHVbx8wj,UnW,gW%!|`Fٽ[}B8:qff!gF$G GBCTxF@ݟ=9w)v@ BRjm;5t!T>' jL-Xr ؘ'Be ͸ҏ7m[PkSg_zM )k6 KF]J13,ۊS4#{P!)? gi( PWI%:H{ʏ[Ot>]EBڰٵ^]oN,,5F0q,V-W=4X+ kmQ^Pw1㯾|!B]BӬmȫpZs]?o/ rj)MuRjϔ$F(X5R {8[?;*&x=4PuU" T@Ui*<,,ʀ@oE-\P̂ v?z=PX7ݛNE!y$6-rpݓv)$;zuəMڡV5Klt8[_C@U}ʍS+Vw =m:{&t~Jkp`S{to]&_8_Sۙ!iؠ>u6"Be*MҔe>+$=:! afDYl N^:.+ױp 8J D1ŜO%{V1{q$9xC!g8z3{lDg! g)u(e."g/5^Wtqr|E"};/1#Scd ރpv`#-I3I=CpDZɸϣ~,3 -6Gz"K77 J+J{VK12\м "=Dule[f\ ދAd'?B~Fq=vBٚ7Z5H*U:۳hs3咜Q@v\q:قRׄu-ͺ$FOTg0eKk3O9sT$[`&7`I-ɕtӌ /@`z罝{1YCV+|נ0|} 19DI"%Y*0[K^u]Bd>c~ f,bf{V2GQn&Ӵ <tmYʺbex lpޖܵp%p|ƱY'PAIq$D5Rh*6@fL*p'K;*{0PmՒqb W !W!ӎi eJ$uBL CG\5<;#@!NIneF44A+:j{'>$BòwL]: v;r58(()\%7k@OϴI3&p{R)}m^u( ? 0H>bkͶN'Pwws9av+WWˏ@.=Pd`nD?2h-`ܲkG$A3:0mСPydi;Nk,O*J p7 "*z){7.ٵgD1dQMYݱE>t_y`> 2Y+'Mbph*@ZhVE>o?ؾ߹B'm!aV\M"9v3"M ( #*N{ `'1cq o{Ѯ7`a#xaA\/„ @ҷ4>eZBiݗOQ =ygQhs'>Qhac,.tR~u`i6K~lANAxPl+~Fm`0p*Eʏ{Uĭ9 s&ks0?Tty&]ek.s-/ML|lfx]Dipl[?NI'rfx?ʾ!׀Nα] 8x1PRgй$\r(0An1)=u|6ZK^_{8984UG#PZ|\a _ہWmߊ!G3խfB;Nm-@L&K*"EH`X,2L:F{6]bڦWekkeQ||f[`%o"0bY WBæ1c #p`2RZoL c0vSM])+)iDJ{bekC#ޞ VV>#( zQP>'r\6ɔXash.>Bơre\"eR<օ3/>K*瀸5V͊WX}n ~l̂1d)p,1$To tc.'6>ǥ oE67ã'j>_/3rgǁ.xXR7[:. sAQr!2r y+/KzB=ՏJs/ 1BQ/-(-Κi} mfxi<#>yI_^x;ZRj&Lq3JM<E <4@L.U*V؀i >ğhMuIޕ*E{8X8&_N*wC6FRrGaIP^n0bxR؉V6!l;h UDh½gVbdt|yԎިYI;m)w;C>V'lu>^B[7>ЏX(4SHF,OPUo 2_6p]}dDZgXbR<~?s͐ |NKXlflUtةlu:hm͡J낐So$2x2K;yPɰ枱]ْ̧sW`x5dɅhLͰ< T(ENl?K Je+XecQ&)؁N^^7*x+_W&yJ*{4yMv1giR , }:"5Ε竫Kikh N%|P.KۦK}A`j|i+gz[Te"caRE9ΠQe_ٗS$'l( ~{m [ڃU-'3'`ֳbCYekP e9{z? H`{u_hpˊ7gC"3 m:]`$[pvSR^s_؄g}y*`>^ov;ywٺM-G4$rv9 /M#È잣] r!HHIs3ajTV! =1zg~yFnpIc<\]Az^pwˉ?lwz qRk'7=̟R‘m\HO'H8@H}t6[JOq<>#W~7tdzPȱ356@C@RК  QuB2Pޕ;n55RU. R<kwM)J6Uat ~Bl ,P#v ?˺mUəaˏ= q~z֗rp830J(.OEو/[>?jSB${ᚱxprpXil:d&Y; W<o4 Ddjd!ort1#3cPo~%1h2l^}I% w'SfR rڗAӘWo+cO|9Mw۟6L,rA )- 7!Lپɫ0k\kX՞ٌ-nЋ1)5p_-6]cނ/0/HZ`#Ê> Nb U ^3{O ^s3{ki󒓿P0Z =5i+SK$lZرD)<Xn"Akp3u_ 0x ^E18B#XQ>@G,S,`s0J* ~uɭSuѿ˧pԞ  \ [M8oɻ`'b30M!Q%)q.X@P"^ȃbFtoe"g9|D)x.ڱ+隷VggBtbtkkXNmJt_83V|#3)zQ!*MKqr $XA3o:G&>~)PO5 YB">@#t ܺa~QYo *KujH h&JX?}(@A(vĠE廄}VfZ?ٕ&ZEgVLAAthlpq c (j!$?I I^dqQ׹ng8A#b]Uř $Z0\79lva6a)r,GA0`ݨG:K!v h\,՘%Lf;7 ю-С&SfD ԋ5C8E=  NĚ[Mc1x,:_Kl,FA -D&׸sN$VPr3*{n4̱r@l芮AB G{\55jŢi\D7Gr : F91Rv8Iey)jb$w8c eWo!eA$\*3 yDB4CK1\{YJi dޢ6:צ>i>mp(dۅ1 &8#1xi-fT^(Y3`0RdCNmrHR x!Ҳm|\` agbmO; 1Cpkx:QXH8:c Nkxo07Uë&M%cםꋟ"z΋5eU rqK|:`M7<f>(tJH|)B't'l/j}}=$-!@'B?J_:C6T(r@ݟ@)MI- L(<=4ś8Y= rmx%љp_OxWS!)։~EkEpK(gڏ}q"Db-)r͗Uhzɗ2\<[9L6]e]a[;\]*h >NĎZ!=1 "n_O漢]D䅙cR2t1q "XWv6hd-uoG_+5Ü X9k\7̓㾱fjpUp@㶕G )0 ]4ۂ"Bu ] =Ha:mWJN1^bQ̡0bc8  n?4Ntq0_¯,:2X+j׿Ma0uH3 f|RS#^qʗn/Qv"b|.wsӿwa~䋹.䮣!BnTgo%w؛@!0QeTJ EJy`jp2ry|ZIk&W"HJTP$,OVSIRu Ng(ZPG}𘌷61dDž)"mtєbʾiESiO] ;] FI[QX EQbo:8 Zj\N:OswbM>/<2Lyey,$ޕlp-9@zh_k=xm)f5Ѝ ʗqơ2VnE*}/@S$bʜ#;Mpi{ ր51?ACE3폝 ݰD8kg= tGh1cϹh-&{I.7<@'zL,wL׌c2%)@W0'  r3{_SƷ;ڏ"{JMf+NKQ# mmҞYaݼ50IJG3)S9ދ!8G:A' {:#.Pw0MV8KH3;{hm#yxyb ^)a zC ͝Mkefx ks5_ 9w Qe#/&Y :; R߽KJ;GhfaWϊj%U:Z!2IqS<;ޭhRy2"WO/k")='(GFx&w䣴 Qff/Yjs8Hbl@yDaeQ >$p\oz%s?iruDžZRI7lΡڿ*%| 73^&>!HޭܳL߁>:v%c3M|.bfz^B (dہx]u"CZҚS*].Ĺh4gxٯaЙP-sB22+PlY톜Ig92m~9o=+@Z%6hƲ? =L8e 㿕B.Lзsv:B)ŵu"Ë_"z~pLdn_N`ˠ'>9(G5w˾ 'hT`WG'{cY[jȟ}$.=KWFhj~L-qD{{&}#r%C] <ٕd i^ҏf>V턔nҫx;w+,Ӱ8kֽW{~_qÙ{%F.xPh[|6E̠@CɇRk|R_\'CZ4uH`~X1v#o_jTfGx1:ߜ譮Ö~ƌ[tx į7M2 =.u?(*Q&CHN#jlv nnm1lӁEb5^ ~{ 9]{F_M[&h31GRUO?m0#{4x냀y.t^*?_Z/J#I4tR.r~PWWRPS@䈔)5# n&uzۛ^8~+Q#A"mN{yRop+k)K1_9i& XENER*ϟj} +/znyE@=;*vNEO !;C偛"K疰 E/Iv,kyK`B=fN%:V;>ՀxKGDN.?ߋDL]\?) 7vxpI iZWW&ɕHX~`NWY3kEn g&Q4B3ZU(HH9geFEBHk)Ze\qU+VI0g5)iAeDo͗gT _ kQw4rպ50w |VURt08V\\'s1 }4wgvԯPLut9|Λ7$HzsOs&esAq^l B=E׀&u6JRǐtJwtll$X R *29rZ3aڒn~ Y/tK\@o@Ɓ8C|:-ه2L(8i4d(䁻o<]S7oI(8,){=>`30O[+2ݵ!Ԭ$g@du.z Oj=9D94=2d7BƟkU^b#;81;rߵ]L)ƼMmFkX#ިdDѩgbu9'.OG8GǶ' % T=*QvYeY3)Uo@Qlkr\S(3bD9ؖa~BEE1ahRb;k?)stek&o O L;pA^TI'/",h$!?.պ>D3ř&j71?tI{ϢfQ6|n|Vp@*H2{[pG ښgH{c92cPiD_uTKxFÁQDC&Ekj੕_g56 :Nbm%C ci^Lʖ 9# 05aP喍vV^VnSoxH2=R.e(9wnG E"*A:ҽN6j>Ueb6V*{.._i+{UNdttk.2W)$;~F)s8"' jXQZn4*}%pFNXn_e #ak=g1MPJ% /͂ath l$?úv[LkF~yH iYqeb)!@խK҄E;߈Ӳ3G"h~eԶLm&d^;[jPǶ VfWN_J?< ]5$]QK]tϝWheggXrRriQ6B#xH&`FH W`ǚwxX))&XD7gz['c}O 8=$6VIoCfҖ從=q=ٳ(,?ݶDg/ AN7Pq>  -qMg_WHי—ƨCX3Bp=WC,0%^lPC㜟6Ok)-m $_o4tHnW$FT]h9FMָLV䕿|H$;-LV@˛}d&WLLfS[YXr> '޹HfE4˝JacmB7pOrW1%KW+Lk}_ ~An!s^ D &: "+>{2>Ѯs$MXBL8* VE31W Y糮 ,8Pg 0gp1e [yuWr`JqU?`նI0ʍp uLKmp6ڀtؾn,clJ(·T%&0wj ~_Jw\iE':[{g(U_=c+I)$ﯦCsB+5slM(һ[xSny}Qal$=Z4Am!gLxm.~-76qdVn> 'Ld|u,i+Iy砸 ,`i۞Ȯx|)0ꊡFff.jq3B$tB ]8gjC+8E*LHY%3K/T}[OkG{l)t58TRFⱈeɡy*ǚA<87{Gdoy`Z rTS^h.`W.I]՚ o)a T4}< #͗^{#Y9ۈSvWW0G'l2auGC~Q0TZ$2 M@J<_47S`mhv(7W;_>R-VECpcBXVwg k8!ZJ@Jثu%E-t"qr]X3I ("f5:9iS)6>$u"?+~9ao!ر.D hfA_>C/J9,SÀ?^}3mu> ޓjxu^px5>~~3ف:Кo9V72ME.vD[}Z8}vU@ݏ#o"അt:at?29FkQ4CbT ND ^!nfA?+LёPZ|G\,xc:y:AFM8*pˌ}$ұiŜ{'S\.2п⓪}b(kfɖ0_hUI%}.E\&njܨi^O%W{_0UvҼ 㯋 0mg۲PqX6Y?[~$k0|/&uid#h:aLt.$X6kLV Ɋp8(9K4 Y& mPΔ"2V^g-!аB]ut6;ibdn. i`0f yt );r+t/^랝ڻ_?94ĢvBKOd$pJ&;//YϰBAoe6ty &%́T u ]!EѤVLAb h"cfN bE0߉{H>K^dAP?0G!9piBlOR;ʣ$%`."Ḱsp <ֆ<|ɕm-"#.?0.r N|¹~Klw*c#GoY.YxY2OBLRNT>uzsfN̅4 [4p[zk\( ?Ì.l_nHT0+×1} ̯~wIڈȌL(s,!N'78C;:HU,:Pob^eV¢SA˾'`@ާtN#L."Exw$S  l_V[:z$Qr[dS]O&-7A2$1it)%2},V,ae/ a8a?,JA*r*h0FQXpc\50eթUu!ۈ7lS"A!onGRJ7/@DdJ0wV)jW+{;඙إkۼI3{c).ݡ^zhIAu)y{XZP4qgSyYvd\d!.߉ATn?xj\9[aVIVqI|i.2A)%@>re(4;]Wi ^&fdY aۧ[ӮM-/+':9Q:H+R4w!8H}襵4&tۢU迒/ז2ݻ㐰/.ʿȶւbU,77q_.NS4pDnp/*KNFH]TɩOo?;l]: |O&mMEH/X-)_> `ȁSUF${JTu#(t4͘'YM;u`1z;ZwiuH/Nvʯw `D _v(z? xZܾW4)QeGMĐF;$8+1|l+OPyw= YPͰlWGhgfqn"bMjLk[MdR05g!f(30UӆHQ~QOb*a )yީnv.R7q jzs[8&Ja;Ȼ`2 hIv(P?YLq9PQOgSN ¶sVp(ZDI'~[6 %Y43xzaʰ)j>]#&R0U7{HR>Jf"y`J{f |dUɪ)8ݼY˵A$&œŦ:gHYy) xVϦ> gO~sŠl݃%C!`%7鿃DV ςDit `,]V^εύ< |?½m.5U8∟4'/QQhmܼ8"C7~sZGy8uh ,;Dջy$ndšOsq:aPcŎ% ˘%w~gs,RG#K,u"DLֳ8)˜a " 3ow_E'DD2&kL6LJsCA.ճ@HŒ&F% 'XCEJW&N{.&?;ؖnp!@>|.(d9ȃyA(/x 9Yo{2~fT lы95q` uj U6&uB܁=~6+Y;p%0? -.SCC|_w kБ| [<6u(ix'Zy/~sRezt6t5_(Vj@覀ı(0As u]* ]}Y$#66WZi:TfgUc1H=|ͯZ\ڃ8Dom!Iyq>J~Ξmoe@kaCj}~7J/ŠBsSf#kFTbOJ dHrU!A8v.RmnzW.[ |kJQx;dto|h  mU&ZlP<Ȩi}oc`ä$pФ3ޙ/vi[ ̪L-M֗ec Js[TB!/K0>͈4[̱[GgݝY?*^f'dA NQZ3U*$\S*J:7Č7[;[dst[ewp(MdXKq:NQA_hRѨ%<BlfʨŁR Z\ѧ~ v yDBtpc,}W mmW*rpsͯ& v 'HlQ{iCDVf,fR5kkѦ*kĬ<554V7>A`ar_O`aF2˝' 98*qcu,nS¼2GJ]e6R*ʽJq3ʒiEbs^Úޅ,^]nNf+]$,! ]XB_t.B҇4XŪv)ˏڎN AҶug*9H"*l[hKttWFL+էO6`SI͇c4<y  %B'7-wl<*Iݎk&@l머8HRcZBs;3"XR'~;6CWTr5ICO+8 ϯ>]w.$hMHʍH7 @7Oʈ,"!HGąS嚤s29d̪'cqю1:f8 eݼ?p˄HW'# ! M@`q,[o= li^=jn5 #cM1Nxp݆h(H?ݜ˂|+FmvBz ԾGI~Yw}v0!,n0t$ӛg/FPX&}gZ4~_A-1 V5|Vum DCc+ V*[ќNF~;Uޔa<صrٌ= FOJ&^*̲SsJ{Dy+9do}b WvHd?e}΃FGK/fD>2ߧQb ~$ ܸctwa4RYV] X`Wy>yZ]y;1W5c_~9k4 Q=f5NPc;@Ȣy$}rR^ oSC(ĥHS:YS]sp8):$cWFִ&'XHQ`*z}iހأX֞NpB^l+δ$jv |u3}Һ"o6) 7 ae l;j$!ͤ\ I=>ɇ\g-eh ǕW%*ۢBY ل$uLB'AqujOufKItK "!]+RqzS}KyzGJK?054Qau?F{۷vwTk]x(P6d3*p*E_n@|I[4jLf40-#ʌ':,]8}" [(hWRSPǚec xFʊ *a>(G´G52ނ{-[|c  J̺R.w /ۆ^p)خ(szN 5]8xvWNIrc%[paEQor2vМ`%m.\d6 m[A%{UI=ktT)_sw_-`& (k0{LZ4Ii"GS$rt}`ޭ_+nߑ+' z0& fB wϥ+EAwإM$XX5o._M:ףh#NnDu|#pQH#YZ7 " aCQZb#«1`Gx 1lWk,#1]{ckǕ%(VnrOA֋&+yUyxjCv,h]d 构 \yuҟM*p,4dG^Q<įUK2|%`ngk0i[3pumj&QcX:ms e @zzl>|>7v|X8k9j$Vtsyd{؜ Ϛn\4MNin@8&A)|r3C\O(qfJ7;W]V, hZJU5O4W)(9%G+@SJ$}Pʴѕحn;1 ʴ]o7]tF4=:׏JUŠiīA:Sg'b=9v'1?d@9TFTÞ _VVZqdSCX-`+k(dqդ s(7 p'/,eɛ!N.fZՐm6+Z|߃9k1>ע3Tt3|X#^"4[Ch P)[7zq'_cQXg DVCrKՆk9an`]J7aHnMl٩͖uz`POGjh H.sȞU9RT~tQ O mɓ~kbj8{U(?1_8$br~5-Zxkݒxv1g(.К\[/̫2|F"ɌÎws[Ӣ1mWs\F2ZցwpE"p),5.S6W3|DXy <[Y 5#g v3M?mC J4eVhn#\'"wG_${,8hh2<d}ʯ_}ΰ{9[Z/-TM;#'qAݞwQgĕ%^aI"w ?v'4*Ai*D#\İ<k5]R>)+LQ#/]t!}iNfY^G~KJt--dd׾ зY%1sW fP܃Oe6bZz.!pf2U-{N_U:~onV%+l=03}]Ҍ[Ԓsx!NKN"[=x\~u3t-M20'C[Xޣ,I8'nnk֧ny*/qk@̕]5-|s!zҎrwk!J)nK,tՃ:zߵ @/f;QxE:I~إ_,e8s A+ .`bv@r2U-886f9H!5$kQǻ/!(m[!n2hRnItvFgAc;Cחh(=6Q9X\W'N^r hUI+gв J/} 9f{LW<] zUOrH۝YAݥj[3wp|@ _DGpG.q{/{P2VP kp)7tQ0Oؔ ȸ산tfJz.JVޢXgU]v4iJM[b uV@ `h;)MzY$جvKҥNLfjq$=/h {j ~4NyA"WP#波TeB^zwl*Ugv|gc / Qs2y}$׿`+.,<*;} $s;Dv))㓒bj5ud7EL3I=p.kO(;T#| Ianoq)HN"$JoSmvutlTgBr;9!Xn8]D[dF'A+X;H[kg|,jG惒xÅ760)F`F'L0lNљ[yR[;-VErGž1"aՅCm]biOY+ 4y}6ҿN<[v}>ض-]Б ` E*l0U@y/_FRߒQmiZX%- ρFׂ%$i~ypr>fk4*,1+muO6HcU ku). ?ʓ]Wt3oP)X0#r ]C@Ն5-թ)iS0Ϳx[L$JST{B=J>Jl'/wT+$Gn- álЦhIA__ ՞؅:˒eN e 8Rdoo5ɕ:"l$CUvbā=7ߋ77#\M w:GC晜{c+6'JZ)]ynU@rѐWZ7#'JPKsZ4<իhzУR\=д݈N)0c^T ~nd4-%*bZ P} &f/xH~ BW0LF&84ˍ}23sF/ m+՛VuAv[`ix8H3ugڪ+Nb׶\IsGˤS~>.ȣeBK KZW yϐe{yhsZ3 ez ՘pe vNmbM|^b9c-kvwڢC[2%f}(Ta ƌ[ <5nbSp w9鍯$E9j祹8t0x5GT*"J ?s+e~pZ:m\bn "yX>"vXIGhe i^~#Φ+=l Z&%x U\EqxIeLµ?׾]'@U6gZ'0[Ȏ! iWDNߦLJc8FoI2ZK_ jFdѬH#MHXAc'.'p/+l7EIҦ7D#K^ptMZKX5J eNp!}7s{mއ|ɪsnT7٧z0nvڋDbT,Tno"P@J vK!Lw@lq{ȟl;5%!gLrTA)֙YypD^QPi?|X6v^)UF8hZ8/"@ORknܐsabEF[~)H&$[;?b*)ziuu܆& aSR4躚$J]לdځrH6_q]X Pzƍ> YɿN~bu3_;'zgYQ]kC?QW$i, Ȇ{?<`מ89idB99U:a9؉"> bXf@ =* WF|\*q²=Li>D`gB -dڏ(;k ?\z}sXLgTTU?3~/}Jk\KZqO-bG]q jjpO(!k>hȴ>$Ϡ~x(]Xً~owNĮ`4@PSPCٴ{aКGA.Qvݙ"Ozq[vh2z`>޻/lLG-^ S X llv|:YZD<ˬ ;oCݕp:~ǧ[$bVX1(9 7gZV跼ܶx.滃2ҨbK%wd f? ѯ3e/I];?Dxo:! N|8,xIYOm?߳M>Q\YoOYUl=>in^!md1?ڤIb_!B=:Kc?*'|NEe/LgMx'@ڣ;z?ʹO5Hr˅qg2&ѣ7o^(ˎwװExp2!WŠ@ݴ i!a^V9+05ͬޯƂOñ>'7ѺIE~3d &e~sIYHGtG͕'5Υ:DyVs@¦43"C-%dȳQ[40/P }y)7Y/>l h:OஂNk_}I}/t_βV-@N^bc nd:vn=u+4+)_iZg}ǧcS]G TQi4pV?_%qhRO6Hw|\ѽX;T[쟄ǔ7a!q K*MzTxnV. ȏ61J#";ˈ,E5*n-\Zū̷7wHrxq\c){Jґ'=Q*W9evu E31塧%TrONJ{X )^3V=__ y$r!S4v@ȧ˞7MK5GKݠ#MTEqiSL|H]/CbJOyI$_-[N":R {psTܢO vh(HH)s"-a9HDbE؅pĥYgcMrwSڃh.-wKշQ#S;POwY* n^*^eUk1u ۅ3l@)Yfݎt χ򦊊LK͵Dq&u{ZIu9c2# H;MNw?-n/5@]OsKW|1rGz`fjo4`WmU1.yZRep#-}23xj& R$[N,`hr}q2Qܚzs6:G.4<\l9tlDj֟3v3vX='$ru3s[vEPj[_G|{4pgHٲay)̣Z;qMG^yoyY$9ޙ1kr%6$ /7"I ` \c 6S[KLGpBY,N. Ew8bxc_c#`GXbo*q.~H?=O{Lvnί xH7γ[ݤhߕVtڽ﷑bdMn Xvs$]5 G 0աJXxKK.dM^`[?1MQ𽸒[H!@Xze76Kr`A3TBx0fҘ=ƒOS1۾(N5y*Vo'l3Įl з)A4+"RI'VȔ2:E0Qn{:f39lC f1>|" (@K*yx‡Q @20N`t iRie 0oz3[$x$@%Fԯj?Ŗ[&\&~K؞߷$}tY]p&#ǵmihĴ/?Kؽw|3ۗ2Cut !:ss%\٢+IB{%P :ocz`Ω*[2|yM Ѿq4Ű#PX٧!e8aRSɕ(+7[;&7~%v,s!EQ.W*B*V\ݔ29;+km4 coKR)-Y/i*OI1NIuejLťn󁓂I']K0-HwNp'!ڴ^paAT}[AKLwkCn!"^#4Id7}Va.+LD,1,`nThdUyԯ!iNfe..x #hLh2r_CڭFgjS lX!ry:ӿ 7(]ı !g*vz^8T@NLk`yb-EgV҈REЩq^s9g ɫP" #O+jK&'pT7@m&dk$?G5DTX7'##wV6bL11,wvaQEu+IrYyz.1D9GpD@egk Z\q5ӚC3lO9.Z0s;T\bo/ "$o1.QRgz1.fS]!Җe6𧻓!"xJt}eVƔ, xK硚f <N*E|txU- / Sk>:˩S `Q'RKz\eS &vxF9Ed;?-{)K(^u$m:l:_LM0{Ӓ^o"gѷV{ŜصabeS:܅ʎQC0*[)1x كf4$qIouuE"2 QQ_Lƫ`%=q<>EctqndN{k _f^3h--o g@K5x_(= 6ɅF4?@'P( (*Xh|Kwl2Sܶ>qI>~.Oxp P/vFtjMAٚI6gj7J'y͛%MX4ybXW*WϷnv0Xa(13jY>eK>8AmWEZ/"2VЕeh)~1c o,Z1{^Ԕ_m= ^Q߷oE@+Aԇͭr);u<=3@z_b%=tX!BSi$Nhc.],{"cMXxpss@Uvkג ^{ /2hd:T@  ̂nbpoLKrycc7HHFs՚c%8âE[h#WlS.mvMN^mDtje6!"sZש(<O͇޳xH@"#??U@{\{y/ ޖ('~9+2O\\ t}D439W O$F5 RM~[#̀'vAȘx#ęڱ"pYA!x*r<%fңڶkjM Ȋ2I'Ĉ|@ׂ;zuzSMߊ))Y8ji|pª29m 毌/]#ܹrJ³-* AJC; H?u0tHU&eI8,eqRpHZG={_kp)Ogӌ_1,rj9g%W|bl $OsGaQӭGփgf'E|`u{A~55&R_& RV5l`&j.>ٽg-!.`uޞovA~9ppy_ =,i8]WذbCf 7=`Ɋ'KbJ};IT{XG0!( ]5}vjA̽Kzqeml뇖3DLKٟ[zs4@Qߗ]0g?xg@xO+_7R@|]-9ۇ Wհ>rP^h5ͤ\q{pO`7K(?CENHGXN3Q&Xj]AQ <"FBd M/|d.Tctrl[/ 7nɲ `@ 9mL4.Q0x|?th.5GL,pKËk!p,H tRx볁A>GUr*H K)!o@l!][۽0=D1=TS#5xtlUzLd8,G}f04h"c59HY]5lד(Y1a0JYjY>QfUXSf@jr"krO$r݄D%?Vfu;ZA[.vP//h9ue;ހ1yBmyʛ Pƚ^x4r-wNDȶkYI 7d|^Idx ǂb?/9L"1uUS} /i6{3w!̾P~?gM!FXtܢ`MQHo Cw)6\]QAUf85v F;UVT|LޑڊC$O͂^**{ i6`G*[ G/~׀UE7&֚TRIa.7px"!~L9w!pgy!d &){rmFc*rJ>}p<*` }g2-G5o$Vנ͆X#͔$@/xVğ)ؼ;yRa D{tӉJ᫙.@${tm.nSߏe} OIUEkc; ut0p!ytK0y*!r/oe q-$*@Zcm'пf/&% _yXkn.:Dbg6^{B2xW CVQ@嗺hn,M_nN''}Ӹut1zK7h(XAvs,#XL+-YdT<_?@aj?k}k$PDCJ@as]fi0x:L ϛ3Ujm=k hvt3LlrV,,VDO/+Qo XE!F:(ۉSvcaQ؀Z_=94<̻0)< qEϤt^%bÂ*pTR2ʩg1)vy`HBL%&ׄ6Msdk*ߠHi{=Xd+:*zYrԳjjD7_2sXV^͞n+_}oU92yz%D?,ݱeͦ|6td{1@L ),v_#PH4fqЖ$v'z1Z|}I|PnO*Cngsr][wt_ˤl!IAR]DhbÅ<ݴ|T왇^8;fGpŚ9d $0 $7rbSCikWc. (_H/|7-`PR[|@t۟ se:>?MjN.ٳWxï: 0u UZV)Z Pㄠ54+;)s $ꇸЀقZX;B0\*C".+ťkAWfWcs~mݼY_whr(Po;i}Nu_` 2G+&=DNs$!] k,â'J^Cki}-ᣁ,NYxg! ݑ)L|ѧY&">X(74+ H-h7ŕf@LːN1kuLءL_?7%Ӻ`2iq9wW(A#5NalO`p@F\6<3&)>ޢDb`Va0&,*42^>.O&tρ.$#ʌj!vJ09ѿ.S Ke a ;\лl?*a_fiΫdzq/JKٝlq '" /B}rT_ɊNVmk^Kϲ2!u tiz \<ji]~㠉 å>GjEgd>0;.E0** ٰvOODM7-bѥdlUWE$l Oj݅} Ըl5!ӢMkUɃƵYRJOX \UGxYq"ZB\ux(dw8"Řճ:}ƣ+ة։d)1 ꕖ,\OMȪo#Q?֡Th@дr^>-wÇki%Vyz3sM+M(Xu;ʸЏSU6Oxr JU\]ZlN9D<,k"Wi#VK8^HofRǨ;lz[Q([A䅷'Di4x"0\D^,KyObX%xtM3!|+yK~JUB3Jq3*r$yh&2!70*3=e>?:,xp'A<;p0@<YeJ|< ;.LY-;O tIn4" fI1bcɥ7ΐIft2U`+](!ʹDG$QuWUTh,E۩_tBaYT|#N1mo2اJgEal$X[ۦ]zjt41]׍+2]0ﭬ`DO2d8t8 "Ă0.oZ:*XgHle*߫5x j=JVE?[a R?ɘzQC/g g"YA v3e gL ^lK5*4ȡШ㈦Qi+e-rC :ٍ\1ţ ˗JQWH~(zlg@tXFC? &88 ,[6JyP _f_C/p 3epצ5a3EŢqf=ٌ+O4m% 6U!6aqdƴeOېYC.%bLHrF}H`<"|A{X~=w,LJ U(Ϭ0+Ω&*kX~܏#w۵BYk!~AHw{I \}!*{?+AɫEĀ5E77hޤEgJWJ9lWk|p1jM];#$5}xnDt|X5H ƷuW"S2h&fW|kx)&"ct |ns>dsxWIJ.'lпY Ӛ1ALS 5L:ӚêtROzH}>,WGdq;J؅UG*-la7We1RFsAonRnt{ u®0[DʏfQ-' 7yr`ݴ3vFhuהgT倖Zs :p[4F-u?zXuքRP~S.! `l2lDvxA((t55+TN<ƍ,7qҲS4쀜rNau~Cx$P=W2E#]]lH| kQs8_WQjDZep3l? g <̟w||a]&7]tn!r2ԗ#rB/QJHo?Cч%ղPʑuoQϱOUD@\6DHD `HB&'9Z8zzqOR+)I5nL@Y4dr?e<1quaO4:<+H4e~f/-8T'*1fjtNŗY=/QU`Poe[Yq"2bAZ019t{Tlf_7J 8S+j5s-ihV70P` uNETO`)ylѤqea+z.qyߵwg=xzU.ͅhn͉^ uMJv4-iZAmMƽt|djsŝrJ=YH7EAL>aREո5 Kث`yTꌨt.L:Zӣz |Y<B`ݓm֐>:Y!k3*`>>py `:U^5Ԟ:j+}V8tm옼<6Q0uJ4#FWb24U{t */6mR.NWHbOpUy=pXGnj8gs''=di Wɍhu(oCѪM\[Tco6[y w˧S< 8\ۃP.!N@ P9ux[Wz`WH 8zƤ!5-o{kf{ó\sʹx@Wq֯vC#ӡpc<RԖQpHU^tu#~\̀q&И!#IYS`EI60s}Y ftoQI/#wQ3jT?'Q^TjnG}MฝPdF lFsQ5^x-L#xwī9@ YnmQ6򓡘w>lD8lAjp^VK$pFhJɶ-%('\~r#k F&=i'.0~ր1 ~}Ƨ5Udέ@ kkb5Җ'B47LYy1},GJ< w,?-8 ˩W3N+L0#蝺R p/Y$AFWBD˶{g]ՐO$"蟑KKC1aۇ"XiDOcXE]s][hT%۹s(0%sTI&]P>[r1 xXIK*/:g3);YXS"B2o>?\%\ 'MxxL9q-VTtt+di*/4f+feո'e B5M> ܭJQqCM2ˀ0[uuA/:a85Pѧ/n`Ԛ^GqԨkqnT5>-z>?`qjO*sD3ºcK:a I}*I)S6ԜtF4C"εr,}<'¥{"ӧ c&ozݧH~<7b:8L6}݅K.LH~Hfb揅RH{#0Pw|%5Rpyt>nk}1]DMKZO<#=x]?q9j\]CM˻L3’c9v8gSWpD`ABaZhD\Ai.~7Tl̆D$m+?S؜Xϙ˨hw6ҷ^ᬫYuQY@hYl␭NOU[?meH]ՕfȤj1irq-xj5LP(9!^SSE;9h7 n'3wj`uA#>,cWUݼ{,]Tl+[-!,6_M[&3%`Ͱپ˗'O.>+(M/~DԴk|%MUɩ<qZP22vÚԵ0,tvM*?&|hMC:߭W4Bɶ| /ȚVτy XpwYeahsg.7GZ^ˉD4ku}a׻ ̉>p;NHjGbTr}/$f&>L2@;wBJγA!/_"ڄuph ~x>jzSߟTin4>DEyXE-IkL^̟N6i!zfD8}2' D&23Q_" <$U;>(EE}3F]/(3m.V9{)fU@eP%i~Xq4`_vs+/.FP`%~ÏNd4Q\Z1BљK^ @qJXN7AH%^Bk7({{.F4hQ7t _ ",YQV+VUHv+Fr6N6Vo/L"NLP;fyoGt Ŵ&jZ 3*Y"ph,l'3 7z3$M78G׿5!m|8?VJbްP|L^'Y'<qh )b/E=MlfBo7“Eg0I(7KL %޼CNah=RO{"8G#Sowiˉ-yyePM ?A/ ݸ M'+Ҋ G *@OP 8mh3ȬQiOB::2p^\߶F/u w'P56.眒miis\Y>CϴE+ \aO?+rGp1}U(i/Zι- (gEPGfK`,aE:,ft&D{k_qwCꡭOjB fZ!a3] R _ ;^-A?{謫y,Z?SMԋ]JRU*Sr#RT&ynM g//oWB7XV%;Bε@Ã. 'Tc+B,Qm3h xkv6;,1"ɫp·ac͛jbbשSĥ(X ̷ <@̓̊ļ|P=p}4IdW0= yHUX8sח,@򢀲cf  @ LSW~B9tI;?J0L s{m=Ù-Asz0e%Z;)`o\mA| 9w[Ax_g\]g)jdy@a uEu5 A(a\4j0"I8O|& h1w' +tI|,_=>x"A}jOy Uo2Ws5ex}G'XjtGzΨs(dRD]I+b98ոߓ`j'{a7|S O﹣M#%C6UBjZO|3Q?nt)+z^`C`+y 9133}[t_֞ "5>bLa]ɦ A%rW[1dg[{s.f2GIJuDb&>SR~ZQƪFr aPH+pg5|ZE%rS,;n1C,Ze0y%4ۛR6/MM S).AYa -w`7^sC8glW OwٗPjۛg!:,;4C@m6*}IQ]Fk6K}gYGPB 2q0+㱒SP.|q40g;qx4s!pKVe齞:LH;Ij ^yʫZPz0>CQW1Cጚ"X>8Ш 4 Էs }{ MVwv-{E d2&dxN ~xWS~*_O7MaVN7e㋩R!OZɼ!**voD}裬;#v^ɋui8hD+>LMT*sVnvL g^Ž-Ű)' 4aIoȽr;X+J4G'[gmEC\W`f'fCRAId)޸ [VyeR=5kc(#3ms-p'/z!Lsgw~KOY` # x;dZyMS-FDCq0o4@s4TB ČH>=mمm{3;⊣lj3w) ^3[sGBZ{ȼenb"1 0 z&4Bн9rMJ'gm?t@x"uF?Eca[L  g&EYֳ)c>l VŠR#+Gi8s "&*G@Q2 g_l.j0izժ85r~ߴpU^j/TXH A͸-ؕ)YDWǀ9iƷQKPӷFGۃDtV~pHfj~o .'\)Iۑj2/)5K,~;Zc_)fk5m͘eKWs%-0Anx'VW 5/%z*G~jh3I>6 M@]pKoHYikCU"&6`ןFvOjS_rSj$%!5JkaGgfބ[?!*$\7ī2:#\-uH0, _ VzQ5ErPh=u ;rės/BDO;Nq3nn57=ֱz8T3{.>@Wtv ئCv񸏔nF6ԕ#YTj h*2Ⱥ!f+D6CrAIx&j M]j`H+0?'μڦ 1FTOJx-џ$eCTn7UA)ɣ"& yO F?i#uk7Y;>ŭ0qßksfad0Z^-uUȭCi0sHoS?Xd|v/:<+,r]AkB2h{jEӁMJ:F.B Ҽ v=10.4W [G̤~.e(C"VwOrM=vIPaF k@[%[Dx(i >w Y&̋تDwJ2=C&N!vG6!$rA+o{? ::7zEƢʞ.lt%}.eW$./VGuj.VY<=e/C(c(q5BjBcw vzG)0|H R8 08v;@/ׁ=Jk\ QC(!vپ:̅tHq ;./wW˄suhR ¯ƆSD|(J-c @YTSz;0^J^"\ MV-z5^ȼp=$Ҩn̮D~,&8C߽IL'5nRp*}V}&ʦSP+B4OsJH˞to7ta @Gd jUYt1K& ~5 ˗xlBX,p50ic@MP#ƣb(uVme'V(M W}+1R4XЋ:c`'M#oHf@&IJݴoEhXΉ!=+NmhphñbnSH >|27JHz^;A3.',~D,q{$|øx+O!k2}3O:JWO`<&t-5RrG¨Pp)[L4ţV7B7OU$,m@uəTNL_Yz6|Ozډ ey Clɸᜂ1nU"%Aj(csa~RK,(En :Ia|cmɄEVw(6AI`m dgՓFtPVjBW*kym\h) N#tOw=W<இs{3`GER~IY*BcHmo/ L4O_K wsHD:g:#'U"G^\ {vEbd W,~Пq79]N%'O-tH_FԠEbw(-XaG[3o=` <8&Z!Ga _(B`=bR<- S` >hW;Q@Bl k}Ҟ 1\`.XS҂I^n aidb~ޑY3H@‡=Fb]W-`4 6‚$ig'%J 9ͭtGb5bä b#c^2rб^Z2FIv,7Yngus׈!8 뉕-l[=kŕetlw ' FM E? ͓%=~;:rLn?7=^>$#KwSN [W<:Ml- R(k5Fxѷ%o ;#^S I{k!<ىh"Ivl6?u֋&ٹCkbŪ _ϴRK n=hzh&di-k`͗W>էBLwkjT{-}~(fulxLP1DŽ*^8Σ UiCU?M Ba,*6СXk6]vuvTqRL'l~]0n3.zJdg>Fn1>C%otwIAΫl4L`'^n{Վꆁ- Eg}`&_T$#f9%6 eqpƪ3Zw(ͳ–+gii.Jj>o1|IhwݦW1Oyv!K&B ~wv c|H=hT |"ɲ|0.b)zoF #r,=q~ tt-阁>x߭.q]Ptt1֎_94:^jTT"BtQvl;ݚ9z 81 n)yQT){[[/'3Vm2]C}x]܀twhx'jWS\E0Ay3?gƸ:xU} K:tަMy~}\0VD%vw@ ?\yA3c̏>8ݓ "]bCd)AyU3Bg} ntGϿ+bw nIꮻߪ_Tu-X B1}'F=>wOnGSʜYlfP1M1z|sʘdk ,t7ܟ)P* /N9`V)xZ]@(;ő=UZ;]P̼0e:"aV RWiEvgXY@bzCwUR:J#Q&b6Ba>;kPHAnF ,[Ȑgvһ%ROl5j5;"5h*„zݢ_U}7}(JZ!o}{pJFY!ӟzʭo!f7^>ly]f\4dM:maPՃ> (u Pl15jӜ"]tϳ&QQ^ FMܩ%hӡE&g^yn) IT-m8@USL3"C} 5I[p [`a HJiVut"CF>9Ȣ9>Aa=hOԘ[<*ў 6ӇHkvm&GfT.!qNÊ*]&qV䳵() />ñ|Xh]ٖ/N5ʖ "mD.qm UfM_5ʮ_6^bVM[K0^qΙ2;bƱf%+&Z2"ѓ.\'u`,Y0cIej)Υ| #YW:]n^õ  cVιb?Ram- gT<>S13S?5U)Hoͭ&%,@4b)R+0y-Dxbџ9Oyve)GX f`4nrEl أiX2[W򛇭 2aYK^=dt ؜kxߔ>E0(CXk)or9|!ԥ=msir6>Dj[Ơllɣ(MLF ck=J>sqGOO.t]%" s⤶gk{%B3B6s[sscG#/)]%C慰50sd<9dY h* }/0<`IJVד`-jЕ#0Rn mcVdU]ZEp1Gk68>d{{9T(݁:K 1@= 9>l78?{MBFB mX?<\XMYvQ]3E/٬h6W 5$@B31su9l\;o 2fvA((A-M:m:\AvU,3\UF圊j DRhs6 UtҶֽ*^6)ks4F$\ބ5|؉PYw94m9 $&#!I0[qJ7oYax9$]l@-Ҝ5[Πмգw^eAw_>{Ds׫KPYP?W=zy,$3Eݢ48u5rlZ2n]/V.=S5SĨ$&u)W0\b_`,l\dƮa<= h::?30:d_!IIl JH7sqd̘e/MMtLj ^k-q3"E wsxPEN/o߱/;HK_8D a@>/6d6);P1pM(n^S*yf'_air=:]K"j^Di%A7Ѫ#RNJ݂+/J v_cxI1> g7 tC'&"-^F+ ۦbf zG{!?Oň]4d~9a͌-_+N m _AA@;5Gpu]h!: E0j,)4d 2C~)yBٝ&$0!Wb ~ ]LJ|͖~c(.?д9r%\2#ok?@y6T:P3{%bo P z.ZSJ^Ahɹc<xQے<*K:nODYj5]N  vCJXE!+o,$wFȓȉ|L'g$n[#m[jpT[ )3nM+t&Z:4jaҜ0:`ֈݳTdwr@= KIFdO$/̪.GC50 g>:OVÓoR"g ~+1k-.g؀AP蠳AG'Jf= ;r`GTrK^/\Bjvah[ꋋSry*_ P]+1QE)'3pmgy-|T;V\1SKj˩${qM}d{ 8pYu5ǟc "Cex7|`F >f-?ܗJhT톗4{䆌0|]oɶeu2œNT[ T5T:٣Hpo]X- K(kpc-~m=!V/&n"6:4eV*0W~\ Y#q /#vY 7.Q䂳o8卤\V!sE11ǰ$&)VsE:]a]z"jCB2 ϥ7K)bI\CΌV4C@ؤ*cy~۳!zfbUk*9$e;FҴ-iE%d|+(5ZVKB.WG PtSI tVtuTg!g9u5\Q+ȮQ$M~ŗ/Ӌe䃋Ʉ_~M}7pc?8 &F CW>C&o |$,V(gPpl$/=bKenCyV +ӵY0 62m_b%|mjKM[䧥6Y~ Y8 ~+w(Jh Ra}+؇7'~&CC2@}}"Az~v/ږns 'BWf3\Psmp0!B=nQ,=@jF0^:b<1pH+>`> cV[uZWC5i>xH,5LZQu[e |~):liQY1 G-RS}嗊G. ~( p'[%6Tƅ_8toO8y~xV^V;NWLJ' >b8+ד qMMD1VI}ɔdi?xD#ܞsn  Ղ:#dR1"r#Q% ʆ<fd t܅rާq/_「L1xeQ!G +D'd[ cΟS#17 ǜS@Kt9  tj8ǁj(Id8)@\VK{x<hgYv'.U66P,d-%KށP ^'sXZS5) M/g3/\h^0!ZؠTʓ.Ap=7:í % b֊5y&tAPɱArBTؔ㭊:9^ja336S2SΝ3{+:ŀ+1 `/;c(O 8?;o*p`TO*Aw>쒸{U⫮ a4F-EefʆY*ZE*,VlVk=BR5@'-ŊbKN p&#{HϠHږ61x9(ǽ\ڱsaj/Ixv9/R1fa>^_b"ND}mR8Ѝ#i\׷yghpCls :Qݮz;<} drꙉ4Bv )D<1'%^L%5(HzGխxכĞJY G眈̒-"@C\JsL[ÈGSoegu!wՄGR)6q9cX^u۵}.bx\mW$:ƙoNRkĴK,%S 1WR}Tr]vS0C=^m*{KFUZijΎa#)CXeF_TZؕȵ&(I33Jɳ=U'ukg귍 eY(ojPPyCy)6V!7:N5]V#Ȥ!KՖ2ΔpG|#luqs9&b;Wet=l aӁB䷕zg) EY 9g)4z"HAI-TLIJݨih'α?H!ZBh J4;d$$CbXܿ*T9ڲrKS?PmF5%bPv"3ŬL `zb7q/m|&;Q4{)yBH* &1`ɋ 'ZqR2S,6gDv4+jآyb9JtP>gi?  ћUQp a)b?/ec};{lAa,8a#tۆ-y\f}s7[͆aʢp1*+^K3k`j=?@fHrrt;7G զԷV3gbx,>pN[Ѽ`[!k|;1ɤy1 ?I,U=Ex(mPDvXQ\P}I*')]'@ܨyl\P>|lU]G}%QY6?!`^¯!aع>:M(TkHҠ-%1S,d͒˱|lqtF9:xiz +ȱPjhw?BD^!lnOW1;(!e嚌\[inxl Z7 h΃7΀$zr#-yY? W/YGj?z?\96"fG D=zZîn_UMNCU{uKvtOiC (| o1}H_~ F c&"0 *50{{@U(1,,8Ѫvf0]RȇJ춝_,rU aDb~`&-xNbri#ɬDo4q"ȗ^z0|vmw~ lJk`D'^7W8S2rVr#sTb D=jAGK[3ᚧq.\*9[Z^w)JF9|;c|8wR$ ðL4L( FlK0eD)k6̷vܖ[nsǞzdQu2gAH;kوY̗AVA\kEw]u} K;J YKF+EyF˝2]( G1YzݠzTK"6 ADKPg\rLv"hm?Y.I#]dص b"gɏ%Zl؜/[w*$L:rO"@h+Zwfuczxa_RN;Gc`Sa>Y.n$.bz n@P8W,{b 0N/Š-@DfV!pTLP~ύoY^qf'Y|jt 5?'fyf[T] \DRT X#7{Ao+B'jYWܸI7C?KNkK |KVDQL KxGTY + Pj6P!iW<Cu}PPaiKU";=h3`K]2ۥA݉sz/ j;6d`\WV3L6o>RW BKc8ȑH|_v8 C3v֩蕦W?SwZOmʩN]/S L(CuZ Vv]SηT؇lMu@FPAiBL:RtBQ>vO fO]qKa<<((Irsf/TbP6#)o CӕP ZXգ\7H&eGs1-EkRl^ONT9W`)@Mj)vB0G X.4/UhM{Z@F8.F ۀ2)`"!0ZE!riYנ` 8 W!Mc$ AZI D1'%_˻!u(DZ=70i=$1l>m  2bH`,ߓΫ=[!gDC]kԎnc<Ѕ:\=VY]°[a 4CLnNĂN:G":V^Q}ng rRڅˈGKUX($ ̯t_a `m[ xQQv4?ཱུG$$~8X:kM3|l ZߧUwِӆ7&;Hh`j+\Л$w[.[▉MF;'[*%/rW!Sݡ~ ; Ut1!RO4s"#!H>P­nCsa*%srJoL^?Fb/uVQVm(ZbB%kփ'Bf!ci+DNJ+WHIY@'<scusyM󠹀Uj&U+u|bP'QicggvP)o'vP48H9xF53|JYTS^z[m}"7{Mo@OnoQ禽 fG6a҃f0$>n~n{_?SuQ\&NZ˅ K[:*^"sI^@N BqYUQXǭ 58'^Z;DuR-ѱNO/[4gk.{+%)CIQ_[:kUo! e Y}ްŋ@6 xxnGI{m|J^-i]T-lCpH CNǜY`Rl8 j&ܮW8[MR יHMto(XOJԥE$MAF9k׍1uu!),Ykf9TS/ɴ0tmxpZz z? ~0>E=~&8'fGHԋN3%ÔeutLWљMěY!soH"]z; 4T8 㛴cQZV,e_FrE1}~(`wA0ٯbZxCըF.5ZM LBHw?eS&k\.~WQyX*e.`Sގ@@r]OQ7 Dk<U?wGnGd Ȇ %ݧ( 432Z8bHFJaEEyˇr7 DN ҷߓnL 6#` ٓhÛ7. 1LCo^7NSZFi8JIkʭ) 3\`[s T7  V60}À|ǩ< M+hIUK?,eA%b,[@`j])=* 8/jt^ Ǿ^b0 Ìޗ^(X8eSwRŁ?k#j}lqk1o`['p˿cɪNle/"mܖͷc0 ~#`/u᪹Wl Uq`u4i嵹F?W0cX$2Kr7-?ɨz z+ +|_Jn=ݯ OC}",pE4+D r䈊ִQot]@r.MTfx/ݲz>Rћdo!J g褘@ Qެ Vi8$v[C0;4i'rd+04~օlwܱ2>Aq>QUVIɂ89iɚNMIEO`٥nϚ Q"B$ @4?GT~48Af@ujg@*UFHCiQ 5>\5RՑCu5d4B_Ʒ@f@=%(w$n{ YxJJӰKXvp2-`v]/9U@:.S'kfvc a7ݝpo'`1q'Gӭ#6p0NOa8ӻppfjrU >IqEVlʣ߹S/7vF(yV>Ρ_gf6Of|cxfl~UW6n8qϪDS&y̺CQps|(ݏ9AN-Dw0#Nw蜷=%Kr"f&P0dbV'瀦mu71.>L#,[9OF^NG6)nmX]i|ͤv o]ߒy1 &5N@8YNOT6Xpd@˲бRTc 0.G))e) j]BPֻ Nq2&STBQfU.;uHH6r(PJXVX ӿM@yVhY/R8B $;UgWkԁ(PC]]IӗriѽrJ1+KSZtp݅l*rA.`i^*3?4G2|r3L5 {gz B~wUaZZᄁrW-=YPi Q\؁'3pVxytLՔND2#g&Hгkx'+'O20fbo:օcӛ6v8*[?e~àq2A9M Drgg6gU؅^C26j9NC'׌ k=}U}.p.!FEiXJ"/-n-WE{4ߒ8ܕa;FEI~hd*D(*Dۣ4Y"4z4-n̉ZA]%>{]Slmx`eF˜K;,Ȼ|Dּ9f9Kv߿aԧCO]ZhjC4CLr7ΣV=Ett%@5TǦ׭0Q*+icxOT5%.N|)﯃b'vqy B؛W[Bn]JJh s?&#ۺ;;0vuOZF>h㪑 bTt-] c7'*l6Ѯq H$)Ȫ}ltt=" Ňg,ԎƆ8y^j"Fb &{nK x[$LC4'GšCx5eo`Y AKMjC-gGk4DH|U.s܊o* -m a"Hg~!ʪf9n(>,Z (dg-hm'dPՖHB˃&oB8ŰM#l;' 氠z ϕ*c=E3jB:>`$b]X7= {,NQY%K|:K B(_K@@"`ܨy hZ+eb`J8vř9=]r!fnGbJH,6Ts3?U.&q.;X"MLT>Q(V3]Ã( Gn]wYPOj{̣+ɼ!~\ζtkIaQIEܚ!  , :{ ~^YJkobm:,FR,*v3xNE[ `/ eazʁK`YlnyH ^A*65S`(w<׷bt**uYvt?+fHŌ66K &U)"Aee]eex!\U6+)d@s@SOqB-HJVNLMhԏDzFŵ\]ȗU.iAOK4y.Ԩz^λj8]m.̺5/.TzaNϮ`O_&!a7VN)w1Fxg.$o8иL52(NS.ԟrTL{Qý ʹ[LAfPLQؘwMɑԐ$nF #o^~l3(ʤ]7tN B2e[H4u'YSӟH% BQI(F`7\6d&BWԉ}UvI|tGF6nxnOQ#yzy5Zs%!!eYƾ{bF"AB-iڼ3Km1}j=OA#EA!&P^ꋖb!7𳾩1y=ۘ=T,}E`=vYK{EgzntA8w5U?(/l|}7ƣ 7ON3MF2.|Gf:YJ7׀w,)ަZcԍ}SOj\%7?Mn@7'w}fX0} 0W6y1H,h[mo.BD[ѓ_$RUXi#5)%zܫX`pZ ow[D~#+7۰ dĪNIaN;]82ezU\i2# YNz&_Kֿ ت#- {M4b.Q<`ʄWtݐ𢉭$.<,]E4㹔|D]‘N39fG H+..Ik-Zqw?UpfVP!U7e٪'WV^Y9\q_tIԀD9LYE(I[M_Aog7~6Aj:rӫyE)\2V  Ji")Ǭuε_냃h䔴Op@O"iw|'f[i0o0إڌUf>ʛLߟQ}TY MO_ )txA#K九-Y 1 F=茍"w{8ǢՠK^ܥ .OʌGiF97s]~h{Q*Cz Rz h LJBpj05gvcx[%G3d`,67`عH,H}`Hq1r;CY` /:+QDÁ ƈ7\=:d/AdN ]~M-JWM,I @֌ f~οK[7DM"`8%\_t21`2J=#'b !Dim"&QEnl_L?87%K;xhP7Շb]w{Nh}Ⳮ+-4C|4Bh_r`/FZ\[ HdjWv&cjV'XB#Vq"h'=3{A=Ѣ؄dŌ՘H$>kQ5+YӸg5缲 6=|\! Ś)&aM6^yʹJEЉ)d( aIձϷх1bUMSE2먾(BP/gc"tve[WsK{D=j?]+66}u6?P;u-̊]Iba:4k1:Ѩ`|C,yd73{:$cEUqSm8."h!}Ĺ)8Q,R(K! ɐG>AkPyOdվvj枝VANMWp:x|l%y[~ygTS2m';>#&v<u>b0C/8V8@rډc(KB@UGbV=K\?0XY8g٬vV%YY",*g^NvAZ U89*`G\ruy`fHZZf|:ޭZK1Ͻ\d$F1$IƴݿE6th%\"92<"aI⟧]]--fV<|=[ ͻ^%)mk5Y/n3* M)Jؙ3wuWFU NՉu\9GeЫ(mƒ mO~\M\xzjŸ={'Xx q02,||"fxHR URCVj0lp!,F9muMYD.tIF4@CqW qZ,@Alzhś-5%01Æ0B;e#> rrnln&nM%Tb|I&s&ܞ-cBHH-c*(Q 4i]*2bWT f꣭Wt5-cI"}4q~ , .9h+n0zYs%zRɅ[SRqvoן]+`L⏧s˛/?5 @\A(X)]dƃr5_H/iȼ@K\8XTb RW#1&?)6;d0pk]K^ =ھ^ZC*1`wvUM~t'pu>t( 15N:drؽnNĻ_Y J2,0m3 ,`QC=Y@ ȆY gM[_ҶP.F3:;u0pjox{6Fsϙqײo$'ќ Ԋ]b{q-kEBBҶ^`8)>_̝ 9>K0Se*RSe荙p$K* Mvo>kC _E!0-::1 ;%r>z9q/Z[oц,jv"YOgY,Xvz]}ԏm,}?5cis&3'Ά؏d0"4Ak@C 51 %fx8KWjQLSVuمi3]pIi#;z3ǣ [2 Ֆޚ0"kn3Ӛ]>h{(~$1.1`,N' TmluDw~6#Of>׵a ",o*(,aFwkff=SA,^Vx֕9+\R hH.p{}#WueQԆړVo$s%|[BFjZa؅~ޕ`=˜-;̾ TX$ %/<CEE`զ'qa@2ߊjpg 0f,lԴ'h$TmsiJp8hd#jNQ#Vj/R'ܤ CZ0 ;0˖b).Kۨ=LRE:OS"+*c@V"|5V*sJ⼰IbnJ$ӽ4[:{u^sRǛ8= m_ࡍfU!Aܲ /荻ei2Bx8QȓfWf{^DQq#atWv|v=U磈z\2گ> oAV22fX SAjk1bΧvWh@jWX)7Li)v&A,dr w(s?ԎI EXrZ+o8yj[W!PĊD,N╃#UkҐzn=w済[xZ5M}jW]l(~A0 JjRw$_#DQV`C }O Pׄ~E3өpt^DJL) )5aEJTyo\~eP8ov݃Gux=2hb1" ʿ>' :ۀ&g]J 447 dcq;[,E OڌlW06 CҧN5sodCY LfQuK,9U:ca*Ym!#r6&8$svc?_ c5עvQ9W"_<Ҽ 3k@>ѰfUaV ¤] ňe"&l"WG* 5T3 vlB5:u8f4BTRkWPm}e rlJ傛BMaejf$%>1O_ևI 1fV~Gd뇍B*` i>֧j9zhu4ʮ& K*R0vwuY^J?5jA*RYR O]ۺբ[^wwIBj=,5qk0u50di !]VJr 8wջ[^{9I0ٵ,ČRky~?C%SOR9# ]MWf@_8 Z{`YsiEpD~$3(7 hAKpZ{:\ [%̸M @a$t `J~y>Pjء =/.s opbǹ36} g]La+ftx\E. Y.sa̛ I]skbHNKqxdr5j`|48ȇ`G:z_AR ?.(n5аliMr//Ɣeoe.%"L0=dF_`ޗpkAS<ܼFw׏UqtN&[hﳊKF0p0>L6={Ʒ4z;K)\-L!{:p9 /bPxDg.,[a'ﵽSyN~;#p)d%*] Y#1c)k .]9τ(tii$/a#@+%-\?9xug+80z65jILmV3})~VtR=|[&6k  kRj蒞 eJ`SFa˚1# +; 4-63`wd|g&e(#+r݌J{aBmR1,&JDn}Qt`hrdaB{s/9ΗJX1qgl+_?9r'GeM^[ XhY3XX,#%2-1 ?6`/>]dXѼcL<[KJFsoy +@"u6庱;kwTָxwf2}~T&+xũrES.;d{՗(@v>$! F /B "&%6oKk*0a&tdN(5r,qՋ< R8*L`z!ID^ԖJKFpF 8(-SBnei1v cr( ?s齎Wn.gOy7X 8TQwm/(c9/`SS騯 gRhyг,O2%(ۅs}E\duSlM0)g>2u9>p:z|1A*h&qr庼fEq8`!F)2G]_cdRS[% onM'rpIMB֫.:ߖ{xGTbJwz⣳ae]RS.vce9} ܗU 5,>4'^RT  as=72ɵ]KomZ*|"47-Nw 㦤"WBx׿v/nyS]560SQYLP 8MYJFd:}kLw x>Z^V|;?XL5l)wi="4{z͕Is0/=^A/ҫ®F.+,*1FڝC5JH<؅|m-oj$䂌eĴ>t;Pi6hM}6IyӒv( ]g jWG,ܘx cnѧAu,Y{HO%_9rmvc;ԤBӕ,ž?;;=s#Gtc hX Xݭ}岜Ȩ QY]g:(NTr[]"B`P %mͯ5txzs_h}pK%ާ]]) E bϘ,78+ڴLDR3-_+/*_k6 2pר. IȖS mwo D&'O6iC.0%Pt"?top; ^|~"rp&R nzH K#D!|k_6*9 1vwken" F@́5bmm-o@a3I!W}HKR22n-|;ܟ}CISE}%I,swQ [V$p !&03UvG?4 lͅL1V~ݮƀ67Ў͢Hb7i%§ ^]N"4t,HkDB\%n3ј\_&hE%;CO/%&RgY֥S5-);&$3R3d{ewg}SrD*Iֹ+~Mep[J96sK:\K^sQp&'Uّ8-&N3a&8Q(nc*#SnL?A'R~|=Gۀ؆& (?+y_KF$ ؆~]܃a`yUFsl8>`΄.0-OG`|y#\BĬ\4?Fb]+(dFvY6^N4S$ۻ<8Phs֡_sNQ;&lS;/tjzE3i^aK}F69vJHS#탩#!6t[G(~]>q_2=oYkp :')ul5xS֦W Vc=Ѧ#M +h/D{{-ө$Uv#Tg,zK\JCď1s">Ftl< h[>u *5v4e}W2>CLcʟ*왠nY-#Tr''/K o"n<J8XaBMJ/d(%~u1-P*fWeglˊs)Vnΰ)߷(v14 h F׬P,|"'E $U\/ %K8 {^YrAO"2[" S3}a(|lv lFoe0Ȁ`GXsT,*|; fU~s-ܫ,Nys|.H |<~{cq/b]^:$#6<-(Ԧ(nw-"Q䏅u>NhN_6!cc& Fl;4羭H=@ʇ_I4^U\"MZY%]զqLʲjG0^Vdy5Y7̽*N=yP$L.n>!,{2r[C\4|Ї|T7?Vgh}E 4(KۇRA2G:8TYDzeyafn}f+F@?p-tZEC׊&/0"K1d@8"4_5Dy10GJwDhG) h*vMdzu@zq(5a}FZq>7%S:yJ1~(\`}8VfͻLDEcJ Q@M5 Zڙckg"L ŘFְ ic܇Ү%7:y=fKn` |2;E!T&LI=fyb_1GW#ZX%eY+ !EB.އ3 K[JA* Fy Ec !)R_FagK2X!p?i)hMkDknxBZ!Q!*Yɗdv\;GCP#n"a 9)P!ٓI6F6࿸D9i3i jW}KOv]X+!!ܫA18Ŕ]PT;7~?#mQ8Z:lyGٳ@rp8W&m0.l(R](TNeKߥ%XoGʈ QH!;Cޫq`7:-c|]T'UlxajR\ EZZ ϋ\2{u%r7&9> [-Q۾ s n쭳ľҁK%Y8%u)U5gwn 4Q/.Ӻg#9skO$oqF g-߅ݠ;mv ,JQVW?QJ:Z.xW0 prsV8*4H}?r,XanKh1x鳀pGOew8Vw1G2o arv&I='~d\FOcavU'+U-4xs[yMg~C׻rA$%pbj; dwI#oh9,Sc/e[AXʩՐ4w~? }A1y8a(iqacTƳ|hm*S-# MBg[GrnƷ=~FyUbX_'"uz$ ];RD׭k_HPY#A>iR13ifNO$_nl~“|,¤.H2$ :e+ՇG|Ll*UAփc_,eLgEyqBd^5IçeG *0iMF=L7twJU1h,f=4X[0z"Vi>غrJhYz7gTAۗEeO., ^aQOXO|'>fi(x"N'rp<0XPr9̳[[(AyKaB.K!Ss؁xjV9Ԟn"t=rPjR@z&f#B']_JЬ^msnױC3 JVNO*Dz}o\`A% :T^v%d%o>t}E8Yyk`-׹Is~7ȾӝctDts)"`X$>˭|6yDP5z fv CHۓ7)):B "N<+}<(-PrCz4 6&+>y8C?ϯI9-<)imPOбFe9FR]4N7v?7=STW)]ͫ1aa|}\Җo`@ϢAl?KQzTttԭ<19VF?OhVWv-jPC5R3;C$ʡh[4r`9 t,}Mv]_EhoP^@L{ /7j}KV"P#`62F#`7SNHuDVbGGi7ꉸF]^8"FFڀ쭌|qswstyT唡a *PL&#wV2f&%rƭQ:K'oqHH vOƓ׿]+:rV3W5*Ѝdn w7jĆ_%✤1NgVxd{ Oϔrx|Uߗn/^e@&~tuܻ*ZF|6KBURy(YFi~ -;̍jP+GEL֦-LX ' 2S2V|PLُZ3 G3у Z-r0N vӖ`@:V0;*IXM3wܩ[̩mP '-Z OWvaU&?h &b(z^O!zGr<?SC 8 wM&l1Qe[e;ܫƅPqq>\KQ̍KԶBaԻOvut-,-KTY[ݔ|(>_ݵ>Q>blY~z]W<}vxR1 @v @b"<29s5PZst S8IwMƖrpzX*Ȇ4w~Bv;):#DC}]«~oăT\nb ˿d=Q.x8ÞP2!g{(pZIU}LOy 2e-ue8_jUcWZ-+.gѡd}d TTP=5 fa>Ͳ&t/LtMblWD%ٳ A[7y `ٛ/ S{?^%'gL]#tnԟMVjΒ~c3[ :܆Ot.P)cVd{v-4{cJ@c=cz#]bXOqa ق=e (\HEB3vc % hхzܿbL0y q":YrU-U*G+_ݡ 3+ph)z7TndSTRR}&`ȬLͨCZ$o28"'v >&T˩b`b-ȵ_Ŀs2e{i'A#-W:Jw,Ã'¾Yh3{c+4IӺ<rr঺}uFxzO.e lѮ&%\YtU|p%$dlN\*Ao6n4O\ 0BȔ5h%w\Ԍ4x偊\oנELy&Koc2&?<'`9 `E):T nÞSBb0JөDCGv<0{Qֽ2vT{-xXQˮeOeid EafU+ߖ4T@Z~Nj/6qԨ9M@c#$@nq؟{&}xJVKfW|(` 4@ {J\c|*Ebx\5gG 1ZiM^g7NI_ɋ]?9^dֱ3QM·-򱨳X"qiĖ3Ʋu& dz?@u|41ֵK0dvΠ>lVɷ~? Pg;+8Zl9XNY45(|ݜ7[/ Ra #V"]9#jE/[J=k\XbЉNT:5-p'.k+85Xl+Z)-c6LWFB~+պ)؎V3+p*d|:s/SI{DL_8p?H ݿA58Q)#"$YgPDP9eVk+i+q;12 "D,bL?oz;x[^Cbj4׏n:}$Qnrpz4e)fa8"ǘ׾9/zA gL l#P6qvZNuL_M!ĸW 1~#®|MZQw`SɍC_ Y[PЎJZ׋=J w6q{;o4hrYMkoH5{*1R N#m_vR\mS ޖd\AMIo} 4f٘'  ⍇ /GE6yRꐅ1ƢgN[gf4`6,UE>.˙)1 <1?K>;+xPB|3#"&r p<KL|؟!vAR\\h0O(1x}e_@|Zﲴ=qZ9Sr)NgtՃ`-?y`[Tw`C~E%3y:PR| HʦCj)+mDuŶWhX zGeȎxr6U7 8S#sNd<%fcSF궦b;ъ$fN2' nBk|Ben_qÖ[cJ àIst*@V~629RSv4MX6wf:Yo!rs#W?U0ݫcs9)bG("FfRnX6)aRG0k@bVﹳu|΢eo!|9zh.2={T-TŸh]ZϮ7 J޻dsGr6aRu6Vx9j aP3<v}Q "ȍ+D馻ہ.yHÃ"wtK\+aUI+IZY5͜ >-UY^1:x;&K[;5t\m] 9usTIk>^ݧ˗Dg0`؂=$./~]'\ʇ~_ hDM6vJNڀ3mKz Ɵق/It? ^R3@M@&jQd?Cv cSn}*c0<5 52naxNnD@mu0EiVȅuT RASZڔ'i+8\=zũBGsA??fѾhr*<ZPpصVf2DJf'@"$|4(Fjy ?P2gƻč^W]2'c0IUCN(0MC7+/t߆Q] ~HORZ0di -غpN\NVNA{M<3ʩ wp% \o2NxW((au\ JvRF%9";q,2fD\,p\$q"YCdlN],/t9Y*n3,%e!1G)uz *CJ~gѣ.gů H[!/L޴n`"Cj?u }~o}kFf4zC[,ק- B m5~muA(oW䥠ߞQBA +%+?͉iO5ЗgZY,zc+IF !TpkYDqM̌zHƅA4TB X۔Ll[mrBJDjwH5mZj2Xj qqoٹF) 6wsoϤDc{XyUAGDe~1wΑk[RǴEI&)u˖@ے, ,楧Ԃlș̗A omL[6QOQ\bA&l(kȌ{B}3'R^.,֤d4cChh7 e;(bS.^Ke:b I Pc2 ,)<|Cl^ ;k-LݘwfcGѥ|Ԗ?lB8+3s7GM\vgq!P_}h_#g\>stC\6!qW-K0 ΜsMyU/X.NG)?a}7vCGU"S(Z@ ޘ'6ZS?{nT14n϶],ޑ=23m!|ב`U1(,|k2~ /0}+1#XT_)sh +#ϊ[UA,P ®Zw=@C6rd1g2VOD/*_C*qHMݭXRdfc}np+$PϚhD\q@z/g@0ط V*AlXE11ymv>%$?'Qiƨb*N]UTn@V 35Ӆjdh+)\G2$y\;Uj ;GmwvUbv5.}rla@E8b(ie&a'VA< o2 @Ӣ˹p~c^ӉWĭ3,]Q4b. jw»}jTP. u.+q//j80ƏJceMvwqr !hu9t0j{2\O*$4w }oc? :(QMKuMy ;o 4ȳ H<xi)? T!01F˾fiBƀy+M A tn0Gn}1x߸<jmVI279۹OMC&{KG>@}:Obj#B~mf|p{-[aBR۵ gYPRePW|ѬA=QDcKV̂C/KPa Hjs b'_ tVStq}NpN uT`T$r&*;] ИĿh4쯺Gcrk]b "ʀR~lywۉY+rϗvRr_nLŠ=,AYoa2"_+ UkN ,}^EZ4X{%OaoϲLxu Jޑ}g˷g֭,f֑-6Nj_SRNQ nգye'xdhɨ*H-t(~?HD*#cY9cZP,S ef6Qse[cO64(zsk$kQ9 z|ds6T؉&βw&Ŋ vkTz>$gE &HEZnaag=b !1tUcd7ϋE_-KSZ.۩AȺ;-vczmO9l퉱jXZ>O?5HLϣ#aBh](Q'Y4=ЅڪO^dP>ԇ&KmbQ ɑﳮ^tinQy<3[aȡ7^"k\`r(S0 b8xdB\"6d#n|-lE4=?Tѣ37v`s5}TɁmQ 􈃆W٬L`*#83 Փ&Gw l3syb~>CƊėJpj=K,ZzmPߨ;f@v5'DKt_~CӈчmgZkM=.> }: zV6zq990{Ó&{x*@~Y ТtZ3,@-jCuS;H{:*4+cÕl+^nq!%)R3r Ϟ8 8ՂAoG5BXD7zHYڶ^U#O Γ ~4. HCZ+p1k ej:͍n)|R6cܤvVL{odNT<He.?ijZl@2űkzq.N!gd\H`T` &粊- /Pz.뤼4BdS=YsGJU$PpHuiS!]&`n)L)薔% SMK 6Qe(G2 +U[Ye_|MX' )8 \ Z#=n׾3H[}4i<[(抚Ȫ%6Q(ouS* s $r!4H02ډYt2z<`MQ8l?r&$i1Ϻ`[*K6۽]0P.I ßx02hjcSNQo;^=EpP~e2]ʿ=)3Q:$VYge9a_{&>-&ԉv>=r= eS gv05kClYVBIچ&竅9e`yo)& &_1AN (v:ƨB^]%vT nm4 ?skMS8`!f;:>{l+s m8R.OսFNzq7rSh|MmNӎvLhUc=+@ CEC“4~wl Fg~>LvnY#ge>ɧҟݵJZIP~Bs`Tis ٶ]^䥿 S_\y&(N #߿۩Jj] I0+)+4,Lzqn(7j(3U|.b0¢$#5}먈۞VHt#v)#d :oUȺJA92s2Ɨ+bbNVte)Hjn (.Ϻj5G\s٦VDWG.7)SS O6)O6ݲ$b*NE5$knZZk8Ms܌w^7HrO4ş( f6p$Q+m!HZm_-guPյz.s~ 4YXBi(/l^s$;z;<#oh`+CIҽWoMa I_JUb zZR@ H%]ߍҩPBHRgVq)UkCj )¹yTP|ݛ&z._QAnvYB哂k ^mR˔bI*~mjo?vofi=b DNoIeG)8gG?KjFmer* GŅ v .{A*$޺,X%("][\?Rœ1!=-!:A.Y@"_h>kQ1LXΙӡVV7#bHP)Wbot&"nb^<}P:بZT\=B &~#eVZ}^mؾ"80ڣ4XC< 1 z_BBKdA|G=#d $#ј7_QCzٻ< ^.;P S3f\}] OOjyLo =*⠏Y`5t8J.X*A\SmwzI:y ލi9~Ax@{zɹb4L$OlCQ~ztO l] \34Z kTe}s'+ۡh٭0 ^_a`[|a]! 3WJ]6O>#<,ǎt]d*2>*(k(Œ.͟-QK-{߿N vp^RvI NG 23)~uPM9|z ;Ï'1$]EOc:7c&ޗItVtըw6"% cŎN[q[ JY V|_it@A(ML}mMT u|H [.t׬m6^M^Sh b>=E_CFD˗jhsW#ޜ&qKpH1eסx[wۢI.7H kv~}TSYEl@_X`W8OEDJ,zǢVys `6MK>[J_߳Oz\̈å<_@.e(l Kb^mX +sTW^ {% ]!btk PGoj^0o3Q_Igw_E`mA JCo&S0T \W<#VH"cYp6VpNxԘg_;dx=4&6YFm\``<$EFNwu4hl|fz3H)R}Y(7(bHs#Њ$fjO?r!88l<,o+N4wH+6m~䳵{ ;bGdؔ/lxp~& Z~cJZͿ'Ї@YX|6e6kS-,F?53ކVC2sˏBNB9MR%sa(tZrL ç5{TnV$b&KC^M# [ҬRхKxĻ{yN}^tE*4=wHw:M42\1/x; 22E!{Nu?u=Kf\ unTݪFci^/8hBz}>&AYx_Ѵߕ%'ŘM.iLJapXOZoEbS @e6X29x>w-BmЂ 9wR)Uڙɋ ]kgN~ҭ408!4QTroz;724WrPVCZcH?+Y\b0TLy¾Z]hrlZe|ƽ/#! /=в+f%̭ AF3,ݺa/1?CZɥM+௼Ŝ0Tɡ"r|i3,|yopAV\NJ3VU [Vmb*)zt~Uegxb..Gc#ʝ1^eȞiCTם ԅ.F'A,BHw@ˊ\-'Zij2/zX5[E-tS lء.c| ES>j;Ҡ6I}tc} #1vJ@OE-:!a!a/u08A)&cDf"mD(Jzj X NhkUd̞؄C1I9B "SWF9w7 ru[hPu7Y*{y O Uy*cv`C:bqo Ϭ2 rYVW{cv)8/lpPRq*f4Dv^ C'?ѧ {э5c`0*<,E#v%kP[k;[' c}'-6󿥯vQH}Na5:^qMW}T]E%]Ru4 y# ΋[2_N6տRlCj`ANCfķ G]B)~~d\؉tzE_)slˬ\mv8 -{ee}! X`=52y+=r Fb4+yDHzP>zTS܋-2@fΡ56Dj깼ewN,,ڙ=wg+2 F)Q%L<8M}q,|kz)]y31^bVF@h>J6'5۞͗O H@:%S{ uVԵȺpEg2<"̇a$pȃh +LHt8lsǦ ]:^pv4[Y}F+;Khf_0f Q3.wϜU(ݠGwrX?0}rgș5gD0PEĪZc:^swXFZ/jea͘wR(O72#KKF| _i!n]E$v$*q,VkOS/GZkHKd. NTS~6)"+dS C?\ߜ|ZtNqF8HCx_'Wua`Fcλ|^L5U<դ;(Rxd{,щ4@U.%\]|Sp>pS7^EƢ;)`$;ˌXcgJJGls|r1 6y3D ԲFw HY-C74AV^ao3 h70Qˣ |Io}MQ:> 2;{ 0sNd5f,t+ٲ=̖TCqgםS4'3&9[oJ8Q-֝nEwl~$c~Hh jxO!j˕"lgj3l>Oeh1rrcң rl _Ŭ߂}о6 8<'ʿ[O =ixq?;2Bfׄ;3PlB@]{ǰYh' Fz1uAI;sfπ4b7ay 4|y C!pY*R3 lSmU5.[ wH>*#v4:m.D 'p ZA0"<è?ِԕu|u=>bq`޲"ӑ~ pBwi@?uAE=pz;\L+w}u/,.b'ކeb?'ԺlFu ۍ„ QoF,uUV=/nɰRR|z!q}V2̭F" ],}GSsTdq0? ՆY=Cj)i@`-I@9@iI/j& XLp=-iA kJF  _W> 3˚" I^$B gdނ7Գ[)'0I+ln7}Wg1x%[Grj$F dH)p?2T:FrE 9j;*/R#5`(aBށ_D`8po-- Y4_e̢/ /EYegQ.@Zؠ aDmuwE+Nk#X6M&ΜǰBjiΗ0jļZW/t)Bf>V6>&Ũ/209|0gd.  (uO],14-_dޣLΕ_Y0;^곚F;Y0j9ŪIɁrǬ$\4}~LMQIzXP>aVՆf y]Qed< D{d`fתJY'HZ6o"8S;ime)KDVPVp&ip6g#- ^FU~mMLo\j%t ۶J\ؼmB;q,7~Bqnr* ?f ז_NP,Ӆ9reJ~|r/׺ʌ|jTݸ,t1DKl3}ʻB;&"T0}Y/)q5 iu-X{*6|ԳwV]$4 Do{>W0ڔTy|!Lh^Ҥ=2^YVD.b1\EW:TgțmB:}euv %ߓx,1k{a;0io(!~8K)|nZ ^b8"7~~B <GFM+r9\/#I,Ν?pg No$_<(] i($:rM:OO_V xow3ŦO8CR$&<ɏvQ"m=cy+@7yfVy X^QC(U U8G C$%mTߜzW6`y)qa6L//7A^ BL*^)YNN=ZCV9 uYPǘ 4I]ÉV@0hq1QQW':sp\>u3>֊ U-r$ ن޷cGW '~&A` %˭Ԯ"vJ(ʺqPQAcO3xIO+J+)y(S*ӍK䁰UAq8᧺b#HU]9*7͐d`2hDzۦ$Cr}]M^ 04u}&ZFԃznЃc'8悐5kɛP& / <[w`xwɅ4 o≲e&ɝ#I+cOإ3b-QiwЪGdQN|g(O~6s 2C\8,ɄMAiU?V<:<`rE ex#Qm;8¡"X7UsT`x4=>')xp|n~ M"pL^PO2zhmG tS]k(K{_=T3f~|@~[5B*SbL4QNiicք9 KL_7KynL0}Lhci;Z}bȎ3.*G +m?Y|k]2@&!}mrçp@X;n+ z ZX3{yAd/,X1 _@a]ē"*,m?x(Ŷ{F|ܥEm:7Z`mYqu9{Sl[ 'Vg8r-PXy7|!YWf^9lZԤEfeOmPvg~|e'V|'t% LLcm c3j&9Q{-F8Ҙ׫؊iBdωb;|Нϒ{whgkqVqٿ65.CڨKK\>VIf< dՃ%6A3Kg(|%t ԷpOTY]p(0Aϙjj&mw)JiI}u ΙմV &mu @I͈B% qmյ w:dT W =e]h&cƩ0QdYy\th5y#34U@\4 [ tyՄNwmFOD[BI^ZF/mBiT B>y! DwBH*w}RgupHu;kY 1OjphZ=y6=4m-VQsʪHx{4Ef.NXg:CSO҂0t}DTXS[WX.t A'=g֔0ٲ gq2[R4imٓ5K۶6m>a3mPsןh3< )m렱X4!/)zaBB?$G|"ϑo!F^X~;PibJ/8Ţ}|@ī!4c|pȀ_{uweȐ9^8CRp);Oʲ^7R.-F>_%؋![Ԇ 'UP|[ѐ̳#Ne4z`dۺNY](&cmR21ӎVp$ip2m{.&L%G/A|z];s(& YJ ;T<ċz\|j![&G9Z q,H#/ȣ:!i An<snN);G$Ԯia sj^@bW*&ɷ{(g<@uA~RnŘ2v" v,[^`86[zGb5;( :SB["@>YP޺<+R5&b,.B$Vs`ra ՘1,Ra;gkhzN:/k"V%d?6oR=7fǤR S*H7<D n#W/ Yd?ԣ%VzӺ{/-Be1dD'&GҬO`0K㴇AVv4dt8ulqW8=߸wܾ-PNv:XMiqU-tѶMTW> ?gV%ELKgRu%џw>ڿXe_~' "yG`n94l[&jfSq#"T(0f̡lsr縪>ݷ@*"Ϛ5`zw}3} 4'N[yTFQ7$bna&ZUAuą|۹$L3^Qw=Iڜ%NۘKK{h=MK#1?L4 ^_~ onD2 /g8R]"j@ЗON+m\[5P0WA QIͨ$;_ɳ0Id2/6 4/7[~ I渊L@|To fجIdB2/39BmS "o٫ȉ)Kʐ_,9%xBS"RsZݫ.'{1iRC$WzEGgn*#l> _n͝Ɠ1Nl =@j3I-.{7YK^'Bs8ۻBz?GXYvTT>;zw@+ĉ\ j*aܻ!?,Da=ԬjLRX.DlBpn|#[# wkg8'%k7Ü$3 :QJaDkqHN%SˆFN*TyMuX\g/!F1 k|Hϧҙ3|4`3ƝKJ *D}SlQLP Ň%TnU ~UA*_ 6/߱" %:!K,j5$=$L+k@l#eQ6s0N'-GC"sT3-ofsW⚧?5[aƒ.] LG 8wi~Ͽ~('')<y!#Hva(azvvM~(~^2*8wIwRı(7 }a/*E및oٙ!+Ltl]ok7z=I:${&(cQY/6f JmSUL!L4MBʐ*LOi_8jK[:,mgwS7'257baN;B~Ss:>^j38XvG4,:cy#~#^@:.2bzLnd;K 3q %T1&lK:iOgŖaHty=})$^H,[oh.v8WgΙǨ~HD͚|n#aȯ'XR| po;4Ft#ӝ)]z+WSiL{|{F=X5l݀'fƊ;2)Cm),K@Z ~Q߀ӨPD>XM5"nҢ /D_рq9ԮPG _wcAY_nW9U5m!x:dNȟSe%Iz&I10$Mߏ*w)?~YøFImk]8 [/5R2g/1wŚ0wn@KpEI2SU*/GQ9#N 5?X?Rnոh\>~͡#՘"Ây"[!2b[59lûJ>tJ"Z[7l758X;AOuVub5 :-9׌1p|II_.ZK$]I!2shߎkBG&0:#O;%6•8sSup?}a-e?Q7d) 2؛LzlՏkzxX$?A"2 MBb= 'R #p8fcQ9ԠILacG1[ 3 >C(h A*mVvqh! ߱QO?TïXk+GVɭŋɬ '?{5Awu<*L/[kmz`-뚕VEjnXW|q3rD`gvL iѡ̐B'.#%Sl=B~]U4(0f&!9}0“z7bO^@6;2*b{s+h]S3CTo}Z X .VV.ԅoETiMK4::[K{ztݷM0 M>4Sp= %{׆O+ꘪɶKn|E4-W|*b2ZabnN@J]mhuܩ!@>@O6oՠjS>)Km`R:ZCIh iCc]R="i,@2_LP&:vSdrHc*@Owu1g *q*"%~uj/CB8zr /P^|+"rC~x58%0E(6%d9?914?_ w6˟3n|M(Mtwp TܿU2f&q“fD:ٮS Z iN,LZx}/::`)ϚsZP=Eh%FYW)ANJYؑpk4S(tjʆzO=b? dN҈c]o; %Iʒb>iu,R<FYܱͫv4=l2koA{ƪHGqad-®% oc ^+̕ ܧUG:ķWM[r/*5% C֗Ş&HevwrjNر2=ӛ뗺SŚ^#@.a)O~)Kvv׉64?עJ=6%|mhy6'X&|"펼j'&WI&,LRt l=%jG,>>;ٲ׿x魙EetrE^ 'X>&pF)xZ*+m4щb Y%W"Ir B}^'SGa=Fjg%}rS@Q QH'8L~? y.^͏1m'WS#O}U֙U,ss5}vA/z<";eA1e(Wf߷^_nK5lQOM՝+ OL!LY jCgg?RwPr~to~K ˮۑ?Jg| MqYkAތfbjB&%DCљ[FpgŠ>[5J,N0J>93$)d5`v!JMRLAdNMKGsm^o_p(sƈ$){bI.3Kgː[DyVҗտ|杨RdBUK?FZwVq(qe;0>;Cîյ\,Ls3x1QpR *plh=aWBI"LZ5W߮>Em2w bf~ <YbwxDaP>}:D %6Lsڍ5N3\3C9: '2Җsٶ/w%!@6RF¬ w^]wvPa![|.9WjMŦzigݘ; PmԀWkh[f7B ,A5ca,}}}mBќLʬs@{@o&Yޢܢ!o7 ºM=LΈ iN4+QSzbp_?Q,ERZ;_MM{ dkVHu6Vs$e@<_!`p:B;ͩ " W  '7&yIq@4cєnSڐ_Ui6]#d= itk̷n:!sRe 1<|!T#X cvR0y5f7*OkѰ.OuHQ7ɞ02Ж" ,Yg'p_R>.:ܞ1@?-; t|ZD%M9-C<5F4@eR5潫O˞#vRf82?QҀX܁䑍w <]կHJzl4˵MϥWg>868~J7S$γbρkHɐpnˏ+-^I].iR BnxI='MzBjY{@ƵiŏoPba|){Ylһp|?o"甎\ 1jrs C1C\ b4ġ3ya^$1h:@8oi|fRY8 <+=o>HAׇ8 Ӧ.H*9&Kw!uW_*V@eTGBƬ%(%4N*lM<_x8qqs ځ6cjJ%W Ʌ^lWcxau-;EE>e΍O 4HuTL݁= qpD v)ݵaxXnIsh_8^h ׂ~):xZ}4q0C6[%14^8PxZ))'ps1_8Xg" SmIҟ<NC-.C%0˷@1B봆z#gvSiWijQnjSIuJU|W>dȣ?M=Aek] CC1ZhSTv[Ų3_+}ƋAǃ#m(Zj@&.[ Yn|X@0# dιx׃.qwkYT!6!1 Y8T8@8 s%gJ[a^E\iFoc3WK.YC޸9_T?j2,?!'_1.D[,yk*9ɕ4fr(+F-D7ǐ92` t{? 5#%6<i|u/䋗Ch#µ}6_'Pàu$fEoiīI[$sN b^AS)\IzOWFO& ;$l>Z2# z1FBqڀ{dR%]x|LYP8 zo9UM93+v a0 QV2N ╆晳m%v&Zm.Rt\$iBCߢ?1PǚĀCnwk5 Se[mkhP&{F}Pүcꓒg*3vI[c8߼?m[-8c*rh֦, _ѧRaЛ4baд5ɼ>ƘQswNx03 &/fClvXҹa5XntAn\/Q ?E32xn1Ɨ&_m߰I Ð039ZiL<gw' \\&^6gn@ly}ꡏp9ٍ::⚱$jdWžt˷G#"-(dg- 9'[T":$sx#=t N.' ds ]4An pnLr5ak=ai!ERn>=;yYI=[{^:a?tngl|}hFP9'ɥeיM fc."PCiDFZVqHyRS[aշ+ćvV!oM8KuegށRR7VrtR%Kᜠ!ed٬d)+|QJ )0wk ~٤\U Oả0o'4K @cˍ֥:=^ؕ-O+3T ]vr Pyfw/8EF|Kk g}OmtK'; ]"1:KV7 ؽ: [UT_BUUono!4&DGG2]^Țڵ}Bz)a)n^x֣DhvT"s3ڑߜG[zPa]r> _͋ Y"cHn&7aefWJ^2jha%6;:F68rY3KR[SQɨ?TPhk#\ָyg¸{E۽txP Lb6ouTo";x68DVOvjdb42plq؏l8!vAAUA$;;0@X}?} v?aE4>;Cu0a-`VKM+}bky6L%&zIK|kc F!K{fR/.QԊV Ե^I/BWvΈ}a5lncUu5ܹ ) ?5Ya [@dqUVq{F'|*/] 㦬27s9;9@S$9TW@0V ز.ۿuV|o&.LRi&dd<yPrDM[A˯Sٮ=}'X;Z-p*g'A>sȐNKҙkLlKj~Vb3j̜uZ3b̔SLhPɘEֵd @40<拳Q=gA.Dý(M5` JݺmUI;4gBq]cIϟk N`[fj2|a%Q}$emq H~hH۱A2:%`σJ}a#`H iwNDZmݤ5^ҽ S+d0L0_8Z4PCd/ G浙x$H[:0D?KM+,\jڜP -_5Έp P8?[x,긡  #&c4WM4 Ө{'"xJ,S\BgA.kiF\5j> m^c%}ЋR)Հ񘈵7oCNvH2Cɍ9t%ִ{@VYTIAw}M]1-3qh!jaNEq45DGՂHFKS"PdTT{7 gI V7/eJT~={ڋX)uT)'\l3Y0K9;p_K£c СV2\C\e# LdV o6G'x1ʻwGڨ&`"syL_#O J̤2)4֎KB0okWSq@C4*kk')J{b̚gzp~,m}YA'w+ ґřZ+$^EmAv?it՞ `= B"` dDzڝWUJr!d++{]_.Y0eX.`1,FRdy x`:hfKDmiI\@.LF"w{͢e Iba~mDKp2O }:V B.ġ,Vlf']@oo2pw)i#kr/j9أ\Գm[6V#"t/ @x^a/BM\$ly/g,2 2@dp6*Ӧ*E,!R}wK28LbPM,'LDkZ:9v?Y @AO. '@oodRФ`̩wŏSNC ї \\L2OB{~BRf5hwG[x\.>[}AdJ]$50hvols /²SfW٥=˔şm_6ni@1VH,MPI='#ޡvEYud<ݛ׹_y>S4y?bܚ'C^]k"_DX aʊ\e$VHow-hmmG9nۤw"[NCd"3cj,㯤 sĹ+Gs󝻭\ 3HP´W/׼-*RŖ峇s[!g7>_0 Zqk~`X7nPB&t9\v 6Rb-1n-sse?px"B1vAu,1KF˱^#xdE6#5+B%G'E׮*sr+ul}\Ķ"Xl߼6lY}a˴7Fm]'[I>u ),4wC `I9"{\js LC}\w~ Qֆ1H)}~jud>^mB-ij҉s4!JoxC0&03L\SLy VZ|=5@-:d7_!G`)dk`;=`aޖ'3JTί6'9bTP.,yP<0QvB k P#luӍ_м˟ 6Ɓ/BaY,-N~"*3a8@_!X1^,;j rZ' 7+ǂC|죂ʹ0l B2>֋v-KF1A|x[}GR7D<&8.wb}wtaL9p 7PҗAU6=dB%| X.|SLY9s27s:15vly&$N;_W^D5Ϥ]q(;O!ҥaʐNbhۯmJkKzՒ@FXYa . ˑ0@ϧ*'*-|L?bu9H;6}ۜ~uS7I{a[}ݸ'1tb>_Y*HFj{1JN⿫#]0X 1a8ᵖf헊݅v6q_R:m 2;@~.|5PzZ;yI7]4JH>>#!Q.;TD*ht"ba)FSX5,Ϟ-!bF8}.!lO^?_vX=n VjשqixéJlagV:ɂ8mNOqνzSwύ|~TNzN,+_Xs9.せƋ&-D"x>KY3l0P35Fx|T, tI._UDߓ~q/D xJpv]2x mUFlQ˧ [/".)Â6)5Y-g\ތL[J!Q 胟8J~u?2 £E[?5Ex,ٺ]֚eRRo@f83g^L6j 9" 2g鄥R]4bٳ>"TIJlE(ed9P$acI#}y0RC +-'-4!WČuKMlee>֎Oy ) bBlJB~Fm{j:(AH*Wܐ]w]74y F 7:3-jDk"^ز]G)+*uObmHӪ#dViR^Cbehyp]ˠ_|lJnЬ;}76ѕPǪ~nj7K5$?:>5D+ k OYA-*zIAQm7x[hrc "SY=BAV;{Lg5&E- i{,wnTq|%0bO'$Y@S"(VkjGF bU$}2no<|Gyj0Lcq*2'G3F@] PHtU-Ce+f|g54Ys]?d|5f-:|i@?u8{}%Ձ# Sq"oF aDɆJw0nƶnlۍy:7g xxsSHɎ~AM,:~J)!ǃ*cbiլ([d?<چzGdȁE$2FMfpmh+Vͧ#RNe=wGVuڟVJG%{}e+0Gm/RpigF]Z 3 UFY1:(3  Vf҉˷Zw njA 6Ӥmh5̍Yӫ+,]UagCJ b@ n j ;TiOXL1|aO\VQuԫf6<ۍG N,B*Gyj@$VuNXJۛ<?wgWR4&s9fmKN.]f #µ/p&U+*G70uCp2>ه(m.t2I"\%'v\rΒՉLRFR9Z@4@Wn0eZfaQx_7 <Eؤ%ġU8,p~ Ȅ^qnE./_aoJqG3D6*Bj<׊~LllV}&Ÿl{Hsd½ֱv?<ő :TF­6;2NRZY_Ŭ+3R- %Smt!JʣrlC4dɉ/O o.5z#^ <N M}$`  zlWu$GhHfWx.!9kK;h*~:ar! /P)bh3+b/gb9\.q:DW" Bu]POPOs p# ͩM/Ԣ!:^qح7Xݚ*\ $V؏v)w<{LR+dB \8윎ͼW.(_焸Pmrty孷N0Ȩ?|XQ29z |YR:Plzy$QcfSɕxg-"oqQLtc|DžAHp ?@NleCUTr˥1M!!N.T8@U1DY1:_ wP|"fBt+E9s*̈́o$0LBwE5ǬMDƗk:_KT\ 1Xk79.:qU~QMU Mk)pQ;;>PX@Ax%>04A(҉d>-ػi$}zpu`K|VvUX<;3LI]NW6J_ ď1rܛ%(P6r[l=wn9Q xuj>JTk:__y@6OzdGH`QM6 ;jx@*DF5J/~2 Z☃4oiV7"9 {xTy47ۗNbfB4w_ac_lF?YHE!)W N! Yo" 콺dd| ѭA@\Sptè>ٴXP'vV2W `!&ݖoUM1tsmPn8jETh.b!E[P|ہ9Wb#V9ftD@|;0.jV8F|Q R!j3')H ۀ)s!$J4TmvUb~8`.,NջY@Y^v8_rߠBf!_.gWmLJyp )nibϏFddQ7w!28谉1".)6Kwvd<_:T(q7e^ '>B 9'j%&|(qc iE] *EuRJuȎjuc!'+n^p%وvXÊVrF:c0^~Yx3T_72kvrf2nȴ,0ON) 6WqZEkd$@t aQKNS6CKB1%~"iWX^eQ+?8WxEm=AZ %<&FU{.5Qo[$s/@%R$`0W~]?sE5'i9`H.:"|y檫xR;FF`_0KWAkE؍ͭyDϣkSP ;I mEV>QtML.WO~q 'P#(ښw7I,~HcsS$:rڔ,R-"R!!gFG| AO`jfiy 2X4t9rvj2!?yJKXNNNl_΀-u u3C*@zD.n4 T]?y$sa1@zg*s6BdLNB[I: ݷTxCMW#Eeϐmiq[VڣPK{Y&"&8ӑ8ޒ RXaes$zgP梟-vX 'ޠg+78VKP# *Wg :mtB(xA+uV8IB(ދj5\ :@+ . $%j?.{_Kg)$ipYr)F,@^U='sJ%kr]ݠHyFAzM@_ydUS#B@|$[-^Z2RXvKi- 8Hfj t\W/K;inNνǣ_j"=ajҘ~Q1\v?6.C7`!7@O4$E*? JjL !0mW o*o<͔VQɨ5+q?:%5YöDzHrenl4E3Ùd$ AQJ,̱Ҹ-9:4}j Z쇷F;YOU-]Zmpo2 DK^PzF-UƖU7环HXɐ@{ c#+-E_4IQr27R z"YGB$;azo4pk %w%(CwwȖ'C \@R%isue`桫3̲a[KH~kFb#LAw*JD.ZgG[\T'Tsno(7'P;Y 5B0c~#qeB6T<ɤZYL8:~0L]^.vtre#dFusѵ5|+2,!@>GSkRLY@lc!؏lU )+~9!S<]I%| p-װun4:x/8aGA 0;H~ɰ4nVVܕnI [eB-ty>Bk;xd"K)Wi\"{9T@S4dx4ڬрLS0IJ2 S>^Ctfc?lGFO3d$tVh*܌-vT/<NlΒaTo~xyfZM)b#ʼH* Ьߝ I;ZEv%p'\pV&_3Ar5:" KWьnĄd -rJ ѿa%g6*4p8GKJLzQۥRQ;-8ΫϷ$$S&A_:=-W&ޏbΓɷh tIifGח~;5=Fc;Nd3>:^~# v%C?>xQVƕ0Q7PVy#Q*{HKxD'r u\ i(51 ClTͧU]F`ǔ+61Gl۳[t%d V+X)}~2RL dlL$(8MN\j 6|T-#z^3P* wfoJ$gϿϟa6<99pGLetCaƹ;r̃(.(ڴB!: kAAF ŋ'r8aOp.>˺Fwv^NeHn:|gHΎnZ:M\gӆp*܏qjZb{[N'JdpdHlDɚLO@#4vw?/7>5afUQ?0AȄ~T i$CNFObP.nU7P&llQ$ Tber0{K:> ;CGnϣu~~2~VCc3]oF<6h;$YKW{asb<ͬ_2˧Am#m:0yk:z͟i%e Dx@4`5h!#Ha ~C.`z.5PXX'|4mS>fW-CR^d q!|颥ts6iQ/e]|Ǒ C^re1Ɓ|'dx_+C2 Zi`ȃu`eF%ɭidsuПHbѠQP"OFH=hcX&%|2qRvYvzc5էƽ&Z=?| $ᰧ^]vY&D)IuEr^Pgց_pQyeUkHet _$vúW5*(Z؄TߩDj>-aIg/eʓ\㧎@ o&Gh1LK8YqdP%VD~ۂyQc 9)u:0`G0e Bu]Չ9obh*xi8C9*9K DKGVq"3D/|T^G0f4Ɠ=LC cߧ>?Ԙ)EKqc -F7zĬ_Ӧ5Ln݅/U>/sv7oyW;H4ŕCϐg%U]B!Aq1QN0 ߢXvg}URk+qBstR⳥}_(Ъf;zQf<{/,@t[Wx +Ay`5beнx[e-64 m[n@Ew,'^_ȬhO`:S7aKb|r7`kZ/"%aH*<{wUa$!'<IQ3K|17&W*9ё0R}y+FT.WS k3O@->6ЫgMzaXҺ38j=>&xeA\qAJJY aFu5p_INLe5LfBcO*@ N` Wjz(=MFZ2 +weAS^\P%y$2}W,`B`5 *+ТiuC.{/#ؒܿ{]<qwl!kEK/e^B3r1W& (JVA9F J*Ru!^GOcB`?}ZME<%v!0E+3Ǒ6N?#uxav]6|ŢOdqȕFN'ǝwQO<9;^xȊ;|:Dh/Gn6a|(4Rs܏'v(19+%Ӏ ei5'[1'۝ymOQ~n4~#H Le&`˺߇mJ5)RG97Wf&0A d%b, 7Ѯߑ)OY;\ 륪PwWWv=ꛩU ֍QWIPL`"AtV<_ѻ cpeeGR&-t%GLW\Ee[оĴa2a_I>h I8H./ߪP9ƗqNb$N liq6~]`$b cXHSK=\eTԾwx!yvs⢱#1Ѡ}ZQTlJR":ҫaנxx| F"!)}iBd0jPƧevNϸnzav̏X.ÏmE^D:Nzh jlzj=p.2Aq@:l)w*7$9!3>Cd_;_.i\99jvĽ5!3 V%1qq^7הW g$ 3)6Zgw բCd@{d[)Up^.ZNEYU"mǻEh@D Iaʷ]j[˃ rT$؀o@ݐK͡Q~&Zd zOWI1=C_,tOA'2`lҚ6}[Z% +SWNmfzYˌ۾.Nt˄ 78#âI!vhېy{ wػ/´~9V1t=wueW)[SȞ:PB67bY Q={sAZ,ce(Lg`Уw4lHk J^4P?pşVw&p u`q`CcycfF]ˌx~wFk"'d)II9o 'K{r^ڢ5l8LaT&S&!i/9&*-cHE@ezmB:cu։>8L_OxNUI ˌRHi*$XlX.(sxoes/P,xEːAz u( Ï":gU<fmj6b+Ŧ1b=kH -,А;w )QEM:H@gƬ؈Dw8 I&aqEW8e5uHtjygt?qCR'IOJUR^6X_:TbjnJc<֌fo=ͳ)r3bm:twtzG[?A* @c6%9[mcjuIyb̯%j%79Iֹvpqeiaz 56^1Gg &ä,}?UYjӉYZ⻰\M$jF|)(Xؖ!V?'CGˏH뭡ΐiA+K0祊rV7tRc{RL-Ze fTez9eo@oQXDMD97as-JHwHHǾ,\Q%XaÆGghɬbΧw|*RUw d})_ESt g#~QҚXAإgrN~?] W1f>}EWd H1 3K8Dzg<;X,SR\}4Q{Ԅhq"s)4c tcQ-KjO4IjzBxT| xRT2愗@svKu[Z$5_k 2SROmw,QV' .6VU =jmO "bf?EmD2$(g).nEYeUo6!MP0- ;{&MFn:7x6.75~0ٯܤXP(G7_S.I. [KɃ>c ,k\Q(`tSٶ%@B1_~\hhY\э?-qP魣|pSӌ0| ť]mgE(>#eφ ?1dpbs a僙[">ߤ7+B4Ɠj< v6ؖY=,U{3ݿ]HbM'͒os G I1^vFqVLR0a%$wJBُӬ F-nI.GWƃٹB\q\)Ms! c=4s.O>k3쮻U'rlL;#$CC$"od"*<@8v*p.⮼}{,/M慵1 3y#Pآ7ɒגXT-c^~we;6)%<)F#Ќ:Ef= _>bPF0NAF8H>(tG=Dyx4!d1sQMn_մEbt!x7 P`i]0/Td2gԜ?Q 5S[ܬX7IlĹOA#(jKKM2Hqѽí|WR#:6%'(h*( *B1Ed~ZԱ̓ :$"$9>F5 0#+i7ބsP~FWlu!QWqžg%b̚ Aq8M4ЍJ BzZRS!IWD.{չ`?f7zaLzqx᲼zh"ָp}V|Fɱ"‚TU67WFW0oh5*Guy.Fz0uTFy3KoET^Hyo|v4`>#-8C6joh꜊ "]u?hayh(_9]JO=Vn*  "F?-@lJnjӁ>Xs;EsdJw4vӪ&@OVAXɾps4 ;zm)j~CmJEE}A11ݤҍ^.Þ?Q;t+n;>@CqAx3MWeWGz3ڌ9RUв]\ZxQ3U86UT5#MDeU1zu{jko TU8*F{Y"GCMOA'N ş^.pp٠7^jg&W fr ~c,=|Yg.{JIB@S.vH]-HvdɮnkBʋ"}kǷ@~1fXzvfɹ9zďsNАF.2xr6[ڶQ [knC!6I!bH[|*^(o\Lb-G&fSv<-0y H݋+Ԥ,jae`ZkO}%Q ǘ ݍԉEZt3lpuwKw0F(?H8kru&FQa)P&k#J,DiD!` ֿ Ϟ[MDJyλp^YZ&[Ƌ0mX$ dzs?XXDR;aF,yP3=`[VMAC>dfu40O# %xf9u 4C(ZNڢ\P"!*#+Z'JCԌ_"֑ Ŭ*!ITKOOhn5)lJ+f;g#A_ 3߈nG;ZKHr#*DoސVjJc%KnSCtlC =5R>ܱ|~C~ӾƷ̖oj_Jڸ0[敩X{MlLqzZ]1.6F5^mX{4Y}(w5t2Yyw/m|vwF cw"s5보* ;a'%kE|ntY$8W hfIؿZ_5IZ&1wa[t997ǑЁwwFq13WFfcYFJ}kf^ L]DhhR'X4c +ζ?^g. .x`6aHzt/(P+n{U)7sRh"fT8Loװl_ߪ@>r}>(?h&Iz90ܓIו@yvo5tvh!. W%MтԪOX~lu!6(XaJ0+ d4Ji9Ɠmn qmZ^UPT3oI [jgIc&\Nl/O}F)p s6KXSg%H]qɥFJӒ.+Mo'3J/8 /BOa7&VH^Lc/xPcl0\#ܨ!7* 74ΪU]"^f3]=A'XwF~S NAu3 2S/0)O'^`z$s0Zjr%Tz$t _NRl|kkZp퉷0 Y"`2N|^9fURc | \k,@n_>m\u!h3g@ΆH/2Bq8D<-cزD<-'};X3OTs i5ޠ{!*G#QPLԥO)PؓNV'.7ih.jr8>;z͘N~q)ANe-3<1@Â&&ì Ƥ+=fL2=z #Fj #Kh欽Se%$ʦQtٟŠ Z5e HV2Y)Z5y뵯JU5YZO%}қFu0Q0 q^D JK%[hEN;IOl fL˅K6 ̠xz"xp,0,DY=$V>&6>}8s^|l娌tM>KUW[BfBKR7ZQgsH6t|}3ړ4j3b:yQzl`.WDNLsw؉`Z$`9uY1Q+wa>z8"J46ھJ_i''g>+ -~Ŵw&UP`4+SErMdc{v)HI{SbZão.C:*IOp">JR7~J兎g1D.zZEKkw7~V|4?y-.J{#d+gMX2=^yuw#V(Sq '>ȕ &Ax6-•ʝ휼C%kTce7RVDz[`&m|_خcp埛+И,_" }+w;=y< @3iF SEo-FQ/BITn53䢰EmDS$lcj dbع`)lqC< LS<>sVs0Bjލ>3 ܒ^/8͐hf$L H \5KIGb<%QV#Bۏ" w^+g&ldaYhGV16*Neg`{C{Cʯ_X<[>oЂ}p(EXc:}?7 h@% !eֺ;ǭ8lNSLwffɱOsjhܡɜvAZc@| rez6 °RSU$vf}2!MUA$82/BO:,ڋ")˳g;<_΀͈V4]rW e>離aXƁd("ԓ~)y4WMK8 ƟD%YW-ׯ=+zK\t%,wg[w!s̓&howD'"H&u#VmCf~.a8vK1ih9d!XrЫhI.ȡ tA-Gl"i/4><ٟXd$PBrۻu 3-˪~_ O"s(CB]w_HFo=$Fz"ݖNxh 26<-lc I&U,u'?(&-O$Ѱ0/3RV~: vjeI?~6dޙAdG´e|"m.J(R)xc '&X@=0iΒs6xyftM:aNd}hӔ?UzAˢV+Rm?L؆;Nܪ5FOQ8~7vwH_qD2&)؄75]Xer^r}VU-cRCtOX#{Ynufo(x[ٖ9&>Je]j~ ϊ׍_@^ o4 18msm9wyCO"z}mvq6UݨZ*K`>yreZ"g$=DFJy =ǎxޏg$e\BE[epjʉO:+{p, m[3i4Q蒟=JQ s6@UVd('*0-#?l#CTS+f?49/?ƒ"ݞ{GWPMjyݫSkRL9? n>-]pAY?vڤ #r:6M. 5Gl&cCi@7!VοT D@##"d"Ⱦy깤h#*evPZR GƩL?o#  Yo]ﷰS tS-͈vʞC0R"*Ag8DbIŋ~}-B"ߎyb`V#j4k9<6m:1h &oʟVװo+IcTG焋0\^[LVװNJh c4,H="Ӧuo2յ?wb)۰!w5˜ǂA ]e4`Kz&c/OD7wUyۣv ?](, ,o#MUA66+V^>g9-vt1Tqcon%cJgVnq6Bn 8 H'̄ju6=>qNQ}LVx8LeP|{(Qsj.QzP=Z7_^v<}lBt Y0ވ5cm\8ml FeAUUi۔cz4 #cixN֓]7Z^? ن!|/+gmm4֩&4\~/+Edb5@.ipE>/ R0VxT M msT]U-'޹v$*Zuz.󝲇t~pN#eGALJV7姍1qDB|.]x&2VIadoݟk˂nC$N$P(EA+c2wƷXp>Z}GsQ$]9\mcƮ1=SɨM* 1޸1G΢ Mۻ%&PZDfB 8N>ء/E6szЃ80{n `jqQokAݲ-(jpXPYCQ'~F)K8sZwf{n ٴ4#D1P^ `6ҡl]+AF(_=Yk5c+?aڻ9whԔ3d ;_PMnF'7hRd/z "yKx}hMEη(PP6 Ӛ[ njabuЖCKtEv/IgfAO{O_[7Bh#C#7crѶtxb޷޸n9 i6ؖ~_gEv3pqqH*zwA[Z@ɩuM-:^I('kɪk";V=)a.!DB[2\4:ea`2Zg 5At[WرSLH&+<ͳNީpU>3`= t"S_^BZJΚij2QSaob1P&I#as{o9iAfS !W׿z$|zϥC\yG]B\?̵\xn i4e zzDO0[\HzAф[t0>-Νl :OBѮY)ۇr!(o3[@9 EVOXx:-ǣuDQ[+ $m(zMoB!3aEiZn@yEEO1ٵؿ`#;SN=`h#ʗg?]5hOJ=;+C*669Sϵ^ZmHf͚ ʸi c0-\u5I^MDeãdA |E*kNm33CiCaC 3QC3 u7u~.+qTiXͰ)>Tn7m 3e:V"-Zx7xws(aڽx!D0"g"oCV7)eL-{^<:WBj~݊نQT BsMoMدYy֌(^YjG@Il҇-%x)@q$& <) tn3}bLe)|%gq ',7^ǥ6ʔ\1yפN Gc5$j,d si}#dQr.RB 7IP`Pߛ E.@u& y'G;2A21ew=r?R~Fy􁅷)?.yg ~/jDr>tIbZSO40g0v5cR*f2@moʎ`rr3dfT؝J^av6꺅-[?Si(~J̦ 7 ^>3tQ!SqoĄi4%/-VH=]m*ЮyhLؔ rXjΎ nxϢA?uޞ=ou#Z[;R]&)bkHkW%+X{>PQy˻`txɋo{]$ؓ p˜?3<#bk4hiם:O`=j0R: 2zLS3;(a-s8=5Ύ&Yc!N,h  ;S720t7Ї-` xalx!"bV %EHͿ /m{zr'md U&&)(4<#bb)1n䶘 [||/JЉzBqj묲2byWNX=@ $gӬEw?O2-v/H (Jx6#A ~?蕨Y ־!΢52h>K6yi;$(qwTk 9/ٟ1@\9%\6]:y.xl HUzqJ*dG@>"P{OukP1fYOaUPSஶȓc<erR ;g'zk177uxP|wy[.v>Y] _xh \ YQ|{}4fh&wiW`ESpv*JOc;C Cy& OTIT@qacY(qb9SEB^!mA^Хz(4 ~swQeyZg"ťY  MD\ϛð!qk2{j)@tK>A6@'m%+3_7*h9DEV aqg AlYB,NTc;=6)j[J 2;WOZ(CEŶؘiffirNѴ_ sQt.g 7 j==¨2OY#b^D1!A|*cԠs9(m f?P-KI/`Yeo(8餖=+Q_]%urוJO}iEM$ 4v6yNwBRAv=WX]$qv\\y˒ ;3a)/_c_<1(n2SC_8c=4q{O3S*]t?*j @ r@BLoB2Y靌Wzb+DD$ G˘K0cEʈTN}/VTpNhٯ `TI8iҿcW bEzkCX(炎|/BvQyLhQP>/w0OcGܥ_J!)xJ2>h`J ?iT8~V{xYͩ3]t$he ]a5Ă8QX̽{Ip)h'1H<صFxq(]{2g9N1*U!57GW/d|M~q;.m )Agz΋w o? {X+lQqծ4cf4lղТfש%fE/~ ɑi`ߣֺ{QUH澦]me7V*]&C$D#P''v=zM'm zh7wK ka0^/EЀ_[ID(db'3 8U+|;Jqkσ!ڿdq3-ţi "WՍʭuL`QO\jq8"`α*iuBD`sK;tj, >!nWiKX?=J` (^I/uD$`KIx(w^٢6-ݚr{]*d<:q0-M}1(U&]w{%_(Ehu"cgdF;w `ku.\v yHaOҚ&95դ}U̿gZ$ fñ1b &qu1A{'p#`-l&Qj=ϔΪr}Y.>q4=IUB1O##x!y,ZȨod$u.+ylAkXb٤㇗@]3TiN _S`Zm&$Ч3DNr"oL;RPJ=(7'Z'0[2!5Cӛ:j$-R26T+ &P.fYXOn}.;I)BRJIo7hN_B4HbD+jOl in5ݨT\Jse^QԖogE P}l`RG{o߂j)s;:jzg)& 9%YjqY&| Ñ-kË26p(?%Gy JrG:2{dɎhC3fs, {7QS`Iuָ0NLVJ}ZZ'Ѱˀ,.= x.6K$$˫!4}xB#ga WQI6r8䕣: tkgd` >*;OsY+ӋȾ)CO8j-o vo"YܓFM %ώO chRV%#쳻q5K6Tb, 70[܈U>\h7s_e[I7vC{G-YQosDL5SXL3 M[Uᄝ;w,-/V@a`v6PWaVuu }P/ݻ J*5d!HD9Db0h`cޫ(&jzP? a&ޟ7oth~ʢ=r4'2 ڦH?ף^t6sHp{Vѵk\'DUd.ƟZ>O U\z#jW%._XnVHV" (߶ u_q7_ ^':u* (4Ay2{4^E~lo:3@?sq9*-Hᙠɂx{Ѽz ֚+BiC)]6ne {kC*!s**c3W?M9c}y4µ6vZtVզEi9^x1'+:4I8 RU۲ Zi̞BasZ[ h8F`nŦO.z5¦ tH`OAPu6[$)㋻noKt0Y,azN /2A kZY,3e ?#ȹ]o&/'<b%|d>G"!M-D;,N%iFǎxZ85or΁^C5VM\{2- ?mVT~O]a xaڑEMQ+:$"ڝk} M>4O.a̜jz~%9{gzN:vM+d44]9ò-42K@5>G `2 %g OO*/ 8AɌJWDqo+F8{0Pwz8(]OFg[>b՞mٶ _19֝l6+d.౪Rܴ/ (2tg:Ҽ ; WqhH£{zÑ GvOWQ T i0^X@.6϶S5k7CBƱjRh\;P>:٢ tkgޕJ|3c *"7LyV"=8W$+m[lV6ںO+1Dm@SIbS)nU?6 G2Y>-^տQFpш9fpj *g;g-"<~D ^ivC S9F߫Goba6> vnNMR2fo|@ب'9vf(jhQ},q֒V$lL7YP a.#M\xu ꘏&LD?b;01bݦ&v%-C˔K'$~۪d4Ԅu~AJPiZs7n4t|i@t"'5PXޤ{& BB]G"(ƒ;0'c&7t{:@OOZyN`Z')4}㛷J1SYGDKVISp $i2WYr`;- μXz۞M9V n'|kDO>6 Ղ2Er%^P7M3x8D6 }2e&KB.{|%mx嵢R]&$k{rG(ГG+]݃ۓ$ *6I{<;KWeme)Z jV*GϪ3@+{ua6O}.4"\\ |K_ .'.j3N4_0 ;Tm;sw l w W!l I!C_l#n JP[jN C'P|o|865Ani+ li3M{4Lw7Bmey L`$gi/sUU=D"~_zЂlܧ6ڙp`G|ZhJ7fߕg;ݪ<+K%_JmrGH4}׀4Hb ^1SWئ[ C "Q&W2Z@`ҷ{yC}$q?1/^QGE~Dyy i`b\=[.Cvx[ +NK i5ya)!T,W88=K.E %5$J>yp:4+靴q&"5RΑ?aZV{f0xcH`5[~(ތ(} H)~HݠFoXVNzFunh7ӭI`fMG#Ky6@"4W~7b'FvyV2:u 3[[C4LPϏiD+!&, ދ6! mQΧ]*$" ğ߇UWsT>!;wW#^X҃+%{)Gm.·7.Rn $GVr,:dKm@Z( F8mAyC^U{:(&pnˢSe%{zafP^ҿP:TO_Ȑ-TIJ^fJȓ2J>/s|oKIWɥ= {E)料GUBBQ ^e>3۸,x.1)3ƒ3Xб#u5jӟ%\ށmB.O#a5#7@ñ2w\kRr<$JFsIw.d:>hӏ{kF ^ b "ܣk@s0Yk Nʹ"{6 >_ۮD%I,Pjb PUiWzexKD?%j-X"*S8:tTV MWg NnOĊaN~oVxaё:@&僜2]?Pȷ<[P!1BU|c{ЉݜsrWաj^SQa*r]Q׌w=cvT 5asHY sz\I7,tvE_|K\[NV>F$! GU+[-TR aM;z?{9Q.;uIXt,I XST g<P$4k,l'up:ssu0[EC5XsP+ֆy:k@*懡 %1 rZ1o.HqV(.1G uFi `X/ZT+_iSALzg`52!ц U_T)(OR|Ӟz;jm"-漥( iju$48]"nx '&H;!_^U|.&EZMũ*D֫0e鏌HھxpЗbEE4@/@vCzY!mSe[rA%* |&w&x ]D5{N&LN>v)x1|2E^ UYNV>7:Jߝ@VG)GJg3 aT_srd;12&!۵s~}jo j3&fi_-8ޭfd" 'UNoM.tf?4Bۻ&X/2Hm,:\l AƌtBڤph2`^ ғDHA iEWo"!x8a2_b* ո6?>к:{\ĕ]{V1>bwfmVGK)VKAYIF7 5+X]:Y9<4ORϕLJm|b47z$W@qHUwqx*"uge0nXP6yx<sʊVRjs1=0E8ˮe;՗d@.x8*[E=WPԁ~b( Vc"6_o;EC ij}xlBh֞ aSML> QC$^,9 /vɧn $ fx޺s|T&#/=Q /gu'Y)ɤdp=Ü6) USHgq4Aa ^׵Buj.k=Zy4298rF$0Tֻ`"8NIwz 2ɺʞBm{ʞvi9IqCuS:M<dyD}Fo/#(aWӀ{-\w[f‚5O l'Y.͍b`DܬSX{ nJ'ah!fŕre5ƳkXbCrihⰱͮ: G)6ƛu^Zu7x86O[~bYI5v(6<GE$N)]Vvn,rpQUƳMT$ڂrtWg(?A11'`5m,VR(9VI҄`k7РmaCG7v7;=fL쨔;Xӣgw"q+~Ouu|yL񌓪{.i6^6"ExdFy!WRFoX/;qw2 TQFR]OX‰S?ul|y@.+B dt)8 hi̞\}YWzU3A5eQ .go택uJ1MhfeZ3oq΄/> `m_zL&czf\DVQK }`rj=Vlq̵s[R7fBioR%q-D=R?A;@V?*Y_:0N3\ٺaAOʙRiZu.IM>ȕ8B 2v+?lV94ŞAG#ZūD:R *u %͂]eN#%riϏ`z(MZ(w< {Ts>+ káb4$!@ R2t4j\x+m4r8U5`@:DtP=HAN k^!#+|pQb-CeiGkw 5~ixtݲӲ&TS:B/`"^w0u:2R2B}t!1t=O\8eJr׃4:}ݽ'Gy^ Rx4t{eN]k< B']^#Ck IoVFk4 fB}Y[2̧\j'"*g֔WZ0u6;/}8/pdhcbjgyqͧr. `2O晅(g1òodOˋ/#uHWCc=cU60k *chJ5+o=G@TS!uvDm|].ڔ1(~)gaC}Y'gkh5礖"/&Ŧa J.CԏFkXpǭಪhCƬXQq-3 6i׎"i[P&w.*KM&@$^s\VU힪hrXtmV!H }wQNUF/=7ij.kmp;}:2^q&/>eU8ŧIGT\@.kg$V1s$1DKb %;VM)z(|>JΥBGn ]T~a??*BL遞Lͻn/h,品$UHTѢlh{bm_LKA|fPm" J]$yP13QvBA0LbICQ ~ƨ*5] 6@ArChV|+]Ys\Nq[Sr-LU +8ML.+7. ` =K?GAcH[ƿZe)FMt!j;JT5~${zQr- <]U,9RqH3!ؤ3:ߴ''va2ȿD9 E?]PX!GX;M#0cxv }qhڂĒ56emf]yg#ސxNs4VDUˢGCJLiz aAM!R[e"P)~VxbʳnVs <&䶒L|8`+E*A'݋jcPC"Ls2%N{=hwCU#zMN/6'䛢Gb@)(v$_#vMy7o,~6Sb;oNQL$\ǔTމ)d e{]TDɠ _SLL}N3s'ͷgZ|Ȝa{Э` j3WeH[*#q2(;`(&ɴD{Ҭ[@TdnͶ TzMWYջP@XwF̈FGD 5`.Xv+|y_v,Ωr|@ Pxqhʀςc-i^ו̯:77(\Xw+]RvɅ;|Pӷ}QnV饷XL.@V|'PLk$+QSj}?5ZDME%Ezf)042|ymRGDr%1"I>Qy˺|V)q-9xcխa * r=!i3'*brKѷQ.#~$fVa6аg5¹[Yϒz~[j·>M6T`N&yz$\rWb6g;ۼTlw@&x>0sF#- 5.$_,$͎$%П!m_8N(5<0J h3Q4n91JE!m^eP>)AԬ]twB <]9WBhzPfwsx*PwƓ{yHţ_f;!Fu 0e(r#?-n+lAIy;YILTxHBѢAs(MwBtD-3.A=2õ#㸟%LA1f69>UÏ]?;( N tɭ8GG:[a .a|ljdT`]a` \R=Lf5is|{{JF9\fғ5'Fk0 [n;a@ Yf&V3'5NK#(lM`R ?Hcts)9Q b,!*}*vu_ãy1\2oB0rߵHhQ<:OjXA~mv-Q .9DjOoE/ 6#[TiXV/r>˱x /(^>{MKT5*V`rɔMXEkN/P^u` mk'ʧi fo`ICL񧒩s<6,~s<u(;^{7' 3m<g5w.gΤ_>IB ]H1uP_4m\T9]Ujr; SI9@&785)U`;zsOf#LF7-"ԥU rd5,.$mgi_(Mpg߈ng*lJqR'Ga _ ^798}U֏ bWT;9l^sQ7C8;Ry%ȕ"* d.wF+0J=`כ{QHi9> n(hUb4 [[Sak3 @S=+ sT#1CKT~QO]cD+ZTF(Is};>gsERo!_JkE<%1D\5ڵDxItXs4(xZo~z $ϾTEvᴢoK2`ZcVQ՚|r`[j9αɝK`XPtXR4C~ZϤ[~x,yu ID&QM+,+8#TlU!p;~?hz\{smф>#=X3H u'd9WZٌkRuqq,! p "lh,?%@Ô\OVްiay6׎M"B$ A 砮udM?cx^am)˴](nnЈXdk;IH*Xլz!9x (6Q8|`iHg~iJu h'9J,V(⩺}BLA(F_9{皐a6H'55y58 Fp=%hjR'f56ճBS/7$z! ՆbF] *"^!;$r3ќӘ90jhz06y&O#ȾXSE ׋Ӧ%Q-XLT@ڞrm'Y/Q~XO;byi7$lT=<ޫ|`Tb 6Ÿ=՘;yړ ,$t3d[}/kz(m\jGVAV>xy?ۿv4 G"\3.ZvSOSJ@7X6I pp:z,[?,q(juRhWs'V} @<*pgVڇ֬%z,=Ÿ4+;گEao=;ދjy{li&MG>i-_-DShmئ /lO+åޢc@1@o'jOAr]YXmS]%pL0t<7 wL:Vf坌9X>8wCPCgzR3t8U֝[P,rf:hOܨQ8wvLu`FɤGj,- j!L}]C=E\06~=+P"ܺM Q{U Yu'rpP@^s|a ;s&"˧Ir1~HcZOR<K]XWhadžh6_HǡuVthb:"aCJ,Yf,VBL:]fxXxyYIϐA=Xo/c8mLjyvŠ%G%rvCrL wwS6C 8|/ڋjEE%T{N͏)^Sp&$ L1UjFn<ԡ5dk?򲵉u]k^ \~y(EXy4)^$.8euaWͻCؼWw`͓ƣN<zh+X˜˜+i!7D7qơ*tZ)\J JuCv=K:Y-ؗUQ'ԛ^ 8#q5/3lڶQlv>Fb נ]o rO䋲/!^g=AݜYȅC15"M7^Lb2!¿(F"ݳhi2@[{" mPs ޠ]vƊ<)S:;VsCvRϠAj-IL ctvtQh2#¹͟((s+.@Ersب0]$wD{/ɢQ ,z(>D'SrP5G͓ |9q,e'`t2fj $#sIü,[ݖD1pNb/](BA{ YDxvUC!::=_# AJ'*'_Êl) +B)i`SǷ8Q6w} itbqͪ &6cm;`Y >'-dt t 7V dȵ\HMQ6E-ịRzɷR'VC|xC -#an86*խ|VS ^-&Nv_z_t~\ .8[r\»th0V~:/º 1Q<&w [mY"3cyxl'nP|uaU??%>oǶ'?ԋA$O&\Zػ˒x5Z9u(9"EK{u߶8pzO : L Ljf?}&@¹T(\ڼ1|◘wKX .&́|Ζޔu-|"q$#4 [bb[ںp ?nqq]% }ȡE> ɳўƕhk#.a':ʅr|WcHBTLDGtKn p݅qLSޜ~DSzM|Ó]j¯bPY){:RYf*غ߶$ro\Mmlz,·3ߦT8EPCH}=Z(g*}wׯnCޢkhͯTe$v9ڲ%=@%h-/mn73oЂZ$e6tcU[)Rq{odLSv2  ۔Y]$KR\9:)0v \=A » lO(ܚ#19BB'AŸV%ӡ3/flbK.hsɈa@n;i&\-bIu[5};'0YT$ ohVD.{id(>VD L2L[z_K]Nݶ3Z$_" 8l1R(X-?2jv1#fyԟ*_<^!g+3^O.xߵO# }~2LL#X՜p'EQ l1@+ñg&'"{"ɄoG6+^1I2kT EhϭE/[mm8hpns#B_dY'}pZؘL*;14,U#CN7j2f޺} 1]q[KK}g1ݛS7+a9Gxyn097W}ЄYL.eY};δG,_JJPZC#9e)K \_ʪES0<9c2Dꂃo%|$A je)ch]rJhFt\TXϏ %B9p9{@I3tʔrT # _J0hD+G"h^d5 CA:=-{+~$f~#C^jSNdw.&:xx"v(CUnp&`=PBZهi "LIxbxwoY{*Khr`86_!UG ih!Cߠu1|e׺uUaSis{77rp£3QXX4 ߧEpp!O42CiYA 1`*3,HD6)X$46NBBVil*ޚ>8*B5|ȧ#pN=t~?{#LIdJ :"ASc"bdy`քеQm˥q:?b<@McYs䞎 ]Ä}2>>y[Bi9[9oN2E&v)Jc.}v,FPOlZgwzЖ?L֫ nd!"AjqڌL3p~r;'4Jg{>o m B'$-4E- 3%0؛h^FIRdo3)ʋUmW/Q yL;~|!#jmYiT?8hE0:I5}'m1Q&nh\;ؕ1gR VO'U(T؍E㖽-dᬷHys# Q"be3WnVX^dSOKdWX2VQU FJ})yG iyxH--F?̇%ڮUiB,., 8ݟV4pZϙ.ȝaНo킗[ûQϻoU]LL l{OR2 R fduCPDD4ׂ n-r夷Esȴ/n5^w>ȁ|ky} @qe|rw Fn̻f5{LtåuE?cEF-O%;% Ik \,n"@E1Agoٯ Ȏ]]T, /.1)<㩌t0/iIm.m.w]I!?4ã5cDK_2<%.SwN˥{Zatw9 PM'c(bf]_&Ix͑dP4$H!U&/_4UbF^|si HH+DP4ph|V] 'W1,V?i^Q7`Zݨ\T߾9wPsbg2kvz]ʕ6"L6I$)D;Oh- kY;r.He Ja{iA}G\;s|w /u?{ 6A&Zo FɒM_ ~7̅^yLsN+("7)ACn/Ӣ6eg|KnۣK;eJ)o $sH\tfAg{ݦPleH|I=JL.l֓ɉ5iw+Jډ竜.aScQ㳌&WOi+1GSttDh,_ &Ye\ -f:ߔTC8^zQ(J%i`HmMX뻲Q J']P hZ닸w !>[6z R\rtxIzP=m*X`YSy),s}Y3Y)k6܀ (s0Iwy:cMfu'4QB#a*V0¿b aE~GtՌ+p%)pF4p>!sʫяuaYx;X_iKo6Ϲg =0փq&> Q`c%U:ǹ)Ih$JrnIV+y3YVZeZ&r°M:JK xHl U]7r7'@4kzn^`W2I;nߘKl9A9Cs-CxW\N>< \ 5V ]!"OdML#^>jũsrw-`Up:TvoŜL&ŴF" +W2B]qqW}7{FW4 ;ѯO|t۴ݮXK&Ez?m-xTlJՠr^tA> C3_mžbQNFTb5*Esށ4BX9Ol4ܧlqS ckéIB}/Y״G挋8"Wہcjj5 lljrVT5U0{̲%p&q+ҊPӪ"\ "|oMFjBg`sⒸWVgE.7L{3CWjX4`QY´~[߀rLg7g[oNzHMPx>Y;t @LwHO4M }xq烓zTF7X-4W <#2]5X֙./Bk|o K4=2:=6%D} ~Ji}dWl_JfiJ5 N5"a6h`@$"Q-OS? 'dp@aǫDaKHbM_^{- ~jHٍLquÏS' aV"Ӻu $;G2Õ ڐQş~;h<ZC&1>қoڎH>95oPuv$ucuu"yBOі\7i7$4ْ8, (5?P.:=$`@Tˋ]/ytu} {EZTqSdAu1N="ޯ{ N1XL|6xƞ ܖ!t ;Qt? +ra߭F9vDi(%Ou+4ueG]>zz :Y yw~͘v<]|h+aِ-܍8<F~3,H=-uN-F'ĆHF? i3[nowda ϰѝ5I>F$h 1¾1RQoon.S|پWRjm^O bw$ ){HegjČ38TMndWnśڝ(,϶Dj$&Wqrd’7GFjQܸBztC d r y-f. qw'z=B 4E?4'Y$6@?ɻ]Z5qyeZ G-qS!L%aM0-OÔ ג=>ܪPDRX|n- t)v]ܵKh _r=hB(ƟXTj਀]G 3?iYOYyٓnFP}M"-%U{!qj!feLaVl݃[a3kDLT!ucS1hm܋ё@u{:I niA K) /vYaD?{2%hنEĜ2$Uʀ&7G!xvV)FsՍ}uh{%bach>sԯ`Y?,y#WZN]B'wMȼ6 UsXJ4Q٬IbTB%mĿжPAϖZ_p[Ҋm$E? e9^28A2V՝ 9%͇c "[SIpxs^:cK\G ;1]jqT@c{~E:>Gqof.Π3 Opd *OEoE c4Q ȝݦfKx2P0Wn]:'f+]3L)icHŕxxK"[rRY 4H DsNσL_ZMsy$b3gxjOɌCFe)Lb6gnP|wpO3o<,j!73`B;ZY%^ł~r(8+)-6ӫ]Η|'ygC#;X /lSƭ& q>MjO `5/-~?9Qb$G4{o hRS 蓅7(>#ԣ#0Q#In˳8yKubJ9) Z^ Bnqv,y*xHO*-WfdZJ6Nqt:\*c(r)Z3(sqCPC9T%qP4GݤQBj]s ېQ6p^l$Jhspmqe$߲ ŏ[lj`N&((aCb OC4ѥ`TJgW]Ԍ܁ 4#2mZ2ٯ l܊&#IZwom!WJ aR2wS2I2)-ـD4@K9A0> :&!^4ձ]0y RN<7fw}Eg \Mv[-)&ÏIԅ\R2/'%R?Ơ4)U*{ƉK@q= Gv| OZ!cڂ>XnO۲O=$}DMv\- d2=L S"eϦ.y$9wƵ^yFީ0,۪09ې Xeqۂj2c^p !ksB~  ą e)T;,ÜRP/Iͳ -RYw5M}ABp+wsR؄FvEsɾ-΀G=Kq|_D$a( uc&ĖdT^:v!As_d {V{,#\v%'fEs@X**}Svm6(ޢ6Rd|oWwPW _~ v6$!h߼7Fح+g@\A1oF2`w1׽G{ՀFi{q2DrME SW7rTs'L^W~Hq,g )YzAp0'=\:1FZ7&OgSeYv޶ suݸ },O.#yJCt4j?0adW<#i8`- qǾDw4냻8 [$ t0[Mrq vu6s(<̪]gh͡-xTaJ5pm}o7001t'Ԗ=U%Y~RbSDcLF :RvX#c(H˷+h^@`׵sT {_w)Opn&^WzNQs@??m [3oZW*Ip]8ߣ1Y 93P_ot6l}\=P۲0;S.';(2;e=$ԉFramzXaHyŔ2 Eں}=ï3\@Rt'^0kr8 \5˄KlC]i+Ÿp/+-?@ǥčk" CҀG!u*rhVsȔHl=Md*UL AF%Їж&#!1A6k7W(V]&:YO)rGJ"[&3䐞2"MV .zW‡MB|Q Ҷ Oe[U>1IFSl i YD4E" ?LHJyyƤzw^ী®}=fl&rs >ӓաyכ PFC\Oӓ ,!;OÛDP @+tuȇUlo\xË .ڛ2>zc_>ln캺zi /(zO3*jM/gq!IdF>I]}W+Lٖ$l_J<MwNOU!wxv҄r[LSfN G("t(qes#PobDn6>rP2k<C_e )7)J}1^51t!bȥz_@If6\uI_q_ `ATLmIC\8t;# iZ!x\I; gwgu3Y:kxmb7o%dQk Pc0W4ˤ`-aKԘ`ޛMH^V=k"RL=F3O@Ms#RF2 <\7HU1x BBNw|G[LK9>PĒ;GFLsf6-Џ؛J~z 6H{,x$!:T5-}]ZA$$P6C8yqtFVF%?+?SA}-[)2JU G0 us=<.` `Û3)v`>CSn2HF"G19mp־\g%T q.vsɟl#i Hidh{p8L2 H5%$ X@U-ԭ:Se2ջkN&Phqb|j s֧ y,UsO.jm69K RWeZ"ViHK~nmOa:Q9!i:+΄>)~ׯDeQ0\+j6s l"Dwl"5tᐁ,C +=}hPP )t;*PM&m~]bcZN^½1u]R'%}Rpé/rY~+O#z)&@#11}#>c~ u,G\MDs3r[l aD{ lL7:ʘSΟ,|"6/2ORrF{Fx`mӼgᇸ:#!P AdJfL[xd}Q[@xP:x2`);5!IAӳ5j,ו&j3@moH)0߰f(mҚ`_ A&kה[%G !RK( /E *C)^tHC";L`j4< (?Lq`.}RM2FvY2w P9h(Zw(SX"h<Ɨ73. 'e@=+<"%ԾOs0'vy}XMaKEoߕ}G|sPyh OgB>סJH㖜?(\tZGa1R75O\?_Ѕ8w6p^W{Ah9zfe3 EYz\'P ,Y8L^JBL@‛> :l7aPwnuȰޠIěz ϱ)_ k1dBjC4V~0p񤖧( Y:^.Tlz(8DUHn`c4y/x7% ~9茔 : ݑrK6ϥ腐3<h Z5sZ< ;35z$KgBa 2o\p{ zL $-Ṫٙ>}:C~) 1--T/CԪu 53XxuI!1qvK\?KQY8DX0aߜ˞^#\cTyŠVNYR:p]!1i[( dG4'tQ!LhQ&$z wkyPCb_OT[ VoAŽة&kYxzp@cL*?6FO3,Ԉ;]$kMi 1Rvq2RB K>~Ŧ_H<4rN &6ȏ`0G $2pʺ41bNPH:1ԉAWYz2]_ H_YӄHɅ] !h]/jiv?cP-,zI)q$""輪:@KFU\Z h7ݮ4XtP4r-줧Y>R~otaڸ&|T@Nz3:ss >-VzZw/V@ /ް۔rMf}CS:\iהD~ugYi<RYo.@{*5ԤXEp;oRPE+¬㏍]j#L ) ¨`jP]f?`e%W40BT=޴={|d | Ŷbx 9>_Ɯ-ܔ DZG$-J̶Xm~$'o4V nuaGg {gzZBӜLy^I^LmC\4e~`iM>ƮpW9tS =]k`WUα+;qa;u_|tﴲoGku })*L8NʗcJ0B3! {D+Nm ra(PqU⮙͎ hP{+f!#.$0¢uM;:v  !V1i_-%0F䴟ܡ+A*yAC;u(ѮFVyipxLS8@=ދ(CK9NA.zb%V0C)rP"eT5r܊U3 z4u1 Td&пڗ r;·;LQ+2|3:}7k0L )p2dy>r,9AFnH%t\:9+-C,~^'' ;|J4N;fƙ ȵp,Ki_snx>H/L*iW_k"!h5},nr*𮒑*ouHqԆAI`޳ӃvTiڅ!JɿjJcJ ڈ)f0#S/܇ٜ8q+ouosܡ3Sp ZuC͒U\vG(ѹ'pP/HF=dȿ{-stm.gL!c_E$} cޥl{'yr wroe'OGI%h92Iy$yl%%Pho՗Tm;pSea(FCǙkxqc ny;ݩ}wjvvhs>gc&MmgRc"RS/i$kml&7=*Z)]$CAe|N|]t=HIE7tق°%=YoEQn`-ĹgQAZ. ?%F:EiPfT-*a,d"aѸ*`BGJّ],EuSBI[L,СDIHc2JGgWD5NfMU(iiucJk9ɂ=K1h&=< ûbM iqRH/1dw8F&*L;O݅|'Hq{b³1a^Z@w&C@,C 8@%Yvr>}0j&&^LE-Efk j1F|UDzG2-o @q$)*qWZ`.J/9shMJYB#%%rDTvKR>'̑4Oxko^ ϊj7jN `?ʹ?>)lwt7ā{Gp5 4Tgc>$'L&SE`;u'4ios]\8$U}jzeVRW d_'D pW&L$9.S/g[myóT=Yz>H=(SGX$,+g+ր=nbha OP7G%ohXyQ[Gf7ann*WrJ%T/kD\a=潋BT<7@ ]#cH!*> cė_תfҝx77:,-IP2o!+:97CYC$ysޗulM|D[3auU8L{A'`<;w0*+ԑ# 7ʓ`,K]XkD6dRq]AMƀ?3ɓ.S5ѣZ$M%`qi~/gWaU[i8[֔hKl!wV#CUNXuΛ[pfOr! $A5atz&yG2&vS &,-(ZZC̴õloDu7n& }Ҏ`y59Fs2bKyzd 5HW7nGIBBV@"Gpu }h>Zs2Ta7l̓[ (w1[m}eQ.-m չ䣔g"<[O2QaS"PmqDT3Q4F4]$"yg@:j;<%w)N!<ޤuZ3ML !lwĺEb]..CҍdsOzR:{ bB"Pih"hgS ?ZޣB|ݔ׬u~A_*:dEaj ;6ɽ3 ɩ@oc#ރX|Δ8xl`rO~k{^d ؑ+PoD`4 N_-8fs.OWiZ9le@R ;&ne 怇D 8a+ >gfjbV1TC~m)Xf8CD9l?1x0riOgH y-ð'oh~*NK6| \=B;Y cU_ѿ6 TpȡѮD֫f XYEHXZㅴaԨݸҙ9qJfy9AmD\(wn>Na$fؾVJV:^/1!@9ffbAʏ q@ǂ_COX%c8_Z6SDZ;P֫Oç>P58r~ѥpԞUS+S_meAMC4^{Pʧ/ ABtP8Sk!QpL-uO]ԥQߤ_O@n_AC"rheZC|hB},~Jr+C0t}tw^ jEX017sp x}2--˭J)(ohLyF>]Ni<ݟG= ܘ`O$lh (#:Vce6+Aer9)|4, 1>+LCc1l44`c)?AeϤ;E (7*փVa7 BDtԄ#*hf \> 6XV K!~LJ?{]h0Iw[ѱ~2S=thS/ ) )sq |GKFUWmovʲO R=[YCb_:g;H*ζ m"%p8*P\q6-hh\0 ;9A~M|cD&Sa9 vN{qv)bO{Ċr>5fQxgZ7 yP*CĠH ' ,V V?dɋv) 96 $ UT hxGRԊIпcS;x5I6*}㒖|(U٣)a5*?Pz~zx L!<|#Ɠ Fbe8XYt-aťYJR C]ja@: /Ѭf|A +!sJ5ʴoZJdˌn=AokT͆8 Xz{J|禼/9‚!Nl\yMXNG䮥ظ=sgF_4$Kc*UO04B1䶙H7;|~hVǩg$s*3I,,),C69g]k+RAQ+_s kw]Zy8 Yi~c5‹LӴŊ|~a.Jb4yo ͲHI^`XD>Hcۏ~ N`Ʃ 4 ie?)'C@i}N!Y﨨-̮BVJ^u~LN$7ԣ'#C=rdPؒPlf1?Xɋ [K<7<[qpRjD)ڄLy}Ls3uMEfMrNˠh/Gr}l"H-|g^% Y޳l ]/%}9s1f{xmk .e,Yn܊l"R2D9AWRE+<_|!:9RS؟"0oXPe0 %va9_4#l^raG-k=)GmD^臬KY!/4l*B;lb#9+awψHU[ޘR0qjC!%ZJ`ĺ'闰r)IU\?er.7yC &cÞXQ~g%fd,}&D^NruN@E;K~ƫJD;xJ*ߨ_,|=0(= JA(`a>>z+]MTzg^X>bg=LW>[>ܷ:6謩r:AOOI޸/4%+ {Y^'tHĘSvʡ ` eӷ-Pʔ YW׬&9*g 1$pf>i5IF$\җfS렾c~(8ϵMiUf(n߲iV>ZPw'ޔklHE{T6 u;דka<9i9puV5 to$I}EGR@z>S_ ~{`sqYE\zqܕtц0Ea!w,i8)>jA'_ Oi}cAWIeJw Z**-iBBVDCRӱf,0^66 p"Ōӊ(^ɋ@u%;k}D|:*d82&!GQ癁?i.9 nؑ#DW'|&$/a%Ux@m a}S[Z+l@7uhp{d2Z[ bZF6V ${@3MGmN۬pbUnDl zjwt6Z56BPsz,nL2襠%)Vt`b92WeZR4Ijr"Lrxe`= {Mo.q]%Tc),·Śn?wx(u;:\@i_9j',(gdBN `:WimD޷>yuBф/eͶk5yW1]~ƩYaM<و;5?ϣ J=:7xYy}eb/&Lձgxֵp*&s#6='oޝ`:OA:Ȗ|]ހEd?&cNg?f&f+5~؏gz#7Jzh2jOMoP}TxJ`]&k-$6GGS-?CY)7;Aw8D1H'eᖘ[V:uHoE&$({+pY>ۣ286l[mT!eo}ƌ*́j!:DK"62pD 4@^kouPiݥ AD,{J$-lQVMIvSvtI+F z +!o҃ (Y:X/bs)6%+[= k#1Z>v BEac<_gNq}?ʹp#27.יAwHLnѨA"+z 'Th-ÈA?_Uף_i Cֳ$ ibmJRK܋Nμ& qd*%j[V#{n @Ҟ#~DY@Ynj{ -Nd7;c1٠sO'/$U9TWюTxkI$ Zp҃*gLq} 'ʔ+rX1޴X4f=)yG zEՑM3EqrC2=w+,ϴ^Z^$Qj#"jq0{&}?'5bts*`7RRUc;'/ >)ra+MýW`d+$B,\g\S(pȼ 59NS#|$²̳_T hX|yL![4";+@+msj`È[7{!BrZ=آ}JO8+pgҁ qaLEuMdnA4{%G+ˏ uhɤr=Wㆧ ϥ 1/p\"l n_!o[*q^ P!Vcj[̸II{iQW I._%ꭉmG>XRDtdFк>dW[ꐝg+^w5ɰd9Vꫛ(=0*55PA5OЕN P]-F 9zh=T:f:?f0`.1Ș2ق6.U8Ƈ?_p~sV5 J--a` )^67D!Yzn<ΛCH_ʄ=婒f&wv5AtZV+&\sZf;N]"f3XRE'^ȿv6Wt վ~%>ch%Q N ,5 A^/nogآ0^MA&*MҲy]|=R5=14Ej0w*.f,nͰA-5`UjvNXjSZ\Ʒ`bK<5G]̇U= 2=9>~ 627"A\?֚>L0~T?Ӟ)v 8/ 8j.Rsj8<9zQF8iL{h,4piUm"뾁볿88tŵAu@u2F v^9ZFO`5Q".V!7zYfM^4%BI%[HMH^:H }z- %"AހӟGݢou™ G*eCoi8/cԎh\S{|XCF:^MD/ aXyS8M/A2uɽL\M/ 3?Vǟ Rs/S?jMH Tkm0 T@x 9N|&k%'5eώӈ5j]4t~mZk 5!PaQt%5jq(Bx  -L ;H4sk ƾdȶ @#: ].pؔX֏Z8\G|w_!z>B}ZyRPjp#`OkxL#a[+3<=?kP.?}ۉ ۂȂ\rfeJpÐxw\ 'wrr6:bi@>J(2f  3[&8TS~q 9>`9s  %nL tIrjF~fy[.˲q|Lwʽ RI}tm"E< щ1"l1۽yvwptn@8K^ZNs=-V'Đ,i#"Jc/XբZVuEs«h@] mV^R>)dUY~5{4 /3rfY{7Xx rIH#(Խ\/a,@}q<]j!iZ! dZ\.'s U)R " @ ǫ.se7sd,t>zhWRF&[@| &z [֛ҫEQ39Fm|/,[@"p.@7ݗt)WM%\fph+Ȩ2" kȻ>qS *_^RW3 J"ut$bZGLq/ mQ F0E݃Rz;t|q*Iϗ/3Q1rt9Lt\dJ,K&5EKe: GPA^;+IM3HK_sƄJI 撝ї,$3A%ekEú)ŻyȾaLKDO%*ūs{bsZN#iӉ&'$A:$7XI B ]6C8s#oe;Q{%gaȤE.MBOAfX3̭tQY=!sȴǑ4njN(ZOGlSi`tz~y0F۲0PPNQ~d@ay{?0ᴇ˷lӮB[ q9MU.-ҭ5:A7i'3SVȈ}))L9ǷJSK?Ǥ$wɆ~ozcm -mN]'W C ])K"X/ +K+IpڂӦ(1*e :PHC+Kn%_@Ct1We:~~3-s`xt2n K6 UZP 1YllE1?9*n2^m-VzC"=8?8JJ 6hKߺ&E O}"&Ox գ*"F#w=8t\IʖD9tSO8ZzЋMob<N6_s@6n0L~ʷGPC!~> QQ?mޚ`"d. e}MX6Sh*T,8=x @-!TaRk0y1M0fب? "+Ȩ*cex1$-ДP PƖ +SZ)舚aHڏ'c8ox33ۻi!;j*Ju2N5L^SN4A-xYws Lvv2JζOZз{Ȃa^'?T43Fᦻ[C(C\6jcC?TlС_sf?+q?niy`duO.]ǥ-8YC?.(vJw}cq2jS{:U:yZ S;~'i1| Vꎛf[(ǿ6h5Q0|#bݎ]'dz$mV`1%U)('Y?Xj6n#04'NٝLq sE5H<O2:ށy;i.V텕h+=*pV^}gwjy[np\z꣝>o;t6"-5&*3@8,SለVD:=EM6Eb_eri[ԒC2j `ZZX礌sx^:nbtv扙_cBEnj9p:#b9[O8}vFQٌm 41|n]~X0)Dt8у-ـ+,ch+noy#+1U! 2D UZapr ~^?fx /!6ru3 yW)ByH.rwQ ǸZW[d5JaÉA)i liJg%ZCE) Xu̵0ʸȩhyuN*w}X*9g{Np~r(5=`6/1  e ?;rtIquqKwDnђ@]^|}>Vp>NIUU}P8W7ƠB-+"6eGRU VrϋZ~u_ƒLΦ3H3=vk+e0k~hsL E |7v5c#R:q "P#؉lIHkt#R~⦕gd8=<Ȋܺ?`n^DCBSܬ1ꚓDKuB̃?>B>@p-v֓vqGhRvz;f-]&[4e-Co[U&E$z;ɵd<4mj S'WŤӲIa|p^OODZ>\3?g 㒡y&l=`?H~I + U?]-^FȎ𲬦~-7\M&o:or:ilVh(J[N*ro7.L]Dud'NQY{e DQmd(SAѷ)¸X  ~P4-G@hkrd_iԗωFEf +,?=1㤇7Go +=Ac (Y ;+ r(PgN-3=B{ERmв#X۲n2i?۝p־:άwF%VoƂ(IS:Q+c$t|hXoyB;2| @KtKqWSpOF {$Ɛ {j7X-6⊑x0,ȉP C|qCvj{sMuo/Lqop&>@,a+TGa`0 F<[a[Ɩ0L)3d~X>lWc1(!T˥4Vh: ]̓t Td#gesℜ*~zS/3kw$0Rgu[j~R^%n-˺7Mf (BW(IxR"eB~O@p{Xv }Z *`HSHTbAxF(T]* +C4Wuǣ@^9g6H]3m9;2b2S[Ǯ3]^ۏ04Un5Ku,VDwPc$dg`l7Ku^!5N)hGq/>cg>}q\/65&lq5R➓Or/NU3TrzXf1PJc/>g hjPSVLxgD-ީu\H\^]1;KכrM{ԝ5cuczGMʺtﯻy#66w{R >V(0aAx:'R&.9sY`1{.3jDwac!WG1[R+ ҶǓ\ht1:Y78)d5ڛ\M`\ _%ۈZ`mk i=J'[3I`SnL5:6ŠPsAڗgO҄`U$7KNp#d)fi+ӫܗZyg 2TcM?7˟;O` P bUi(bP{oͲL7 U7o.{.{*(` V5,B/n⇍ 웖Y&,wЯ߿_]!p6߂A'M\3@<ZF,ŮeeTAE }͋sqH)Zк<8|TSȧ` >XԪw=3-Ed ^VV!_<5cCr%r!p>;4Jj m[ آ;3?e A,xۆo=eN6p =7AŹ{hޏ.pլD)G]y?u_vf{!bgo鯻ARYuuatPaǪ(GSdg*\~^v-9)>yU]aް,_\SpȾ@2>XX{X!c'G䡜kdv9k ~n\gpBkKBq? PmVẢٌ (F2 )$&aٵ,9.$"6^kMK:/Ea5wmKl=ͽ@W۽amSwk^;q[HhŦ%:/N~Sbh. e_X$I?bO,bgssk􊐩Qlf&n-O:?-@NZH|<({j+%@On!rDu&J[0~̳Yv'RQl5tHly&iC8w}Il0pyīKPvŁfaGuk&jso gTn<;EmU hc_;K 8 yG9MSj$ԛX١ɮj_ZRi/? ֎ >ͼ; lz56h&h}]Ya懚%VpR_ < zB .H]1xn;F!nJJi?п%ƋѼ0-ӣq}&,gZ 4{6x5Rc䱓K|!=X]ѣ~(~$ڥ);"CЄQo,@Q /ŏc**?]Lm] O)LaBЦ%ڵĉm+HKI4yxaQqhu/n*~HA eHfۦF68_*zHEDU`˸A)D}hBNeR֒_U:znnݞ0>(wMJv[ZFNMV%x]uؓ ں!5; 2`RvPz_>Z+6?fG9 1frSf |!Ք! >MyϻW.1,Q J^h ģ J.~VF|$^%K=(%'0DԔ%;vЂHnݡĤVжYVJ)P:X~R29y9Ǽ?N+4µMx}`A6hwxw-WHܼ?@ߢR2 |__B%)h]s̎' $,4-y\aTk-fh&M`Nyb GHX$7?殃I%;f _.XB%Opk92">C]4N{1s֒*\O@^dt`[5B*+ɰQp6/cTd[KlUlf9QDW=qk:||WEVoz)l`x.@c!ӣd8|wxǓ"'ٿ̇|34UR|<Dl>pRQuPC#L^y5*[iA!o> <0a[Oy*◫<,ͿvѽӞ1?Q)=O?CϦ܆Kah G]qL|4E`PZK]?{xr5J@W %y󿒉ٙ?]B.e\j;Ҏ9ttQZ&<_9spxʌtLݶ]Sk8t ilc} ~fIF.PѮE|z Om=;V 쇓clF-4 }k+œy ָ vEZb eo|֋:5 Ic(-cAγ9au1\@3 CA**Z8=~A_~GAqXeSFk-ypU  ]n"Q}خR5}%rW$m2 Ф z4TNVq6K2X)8!aOcGh*o'a!nB+Hz6oKj_Q}f)Q͠4N&L4L ß[w H0oM1cc!^V#CZu[e->\ zcEM;!`k_ Ċ7ޑx ԩ~eʥA5d8~DF̕:&"Fړ_b)U ҍ8y49;ۮV !BQ⻁F|xGV'ҿ'}Six&=%PanlGоMGNʟMkd rȆsSJw/UzhYǶZۍF_χI$oQ2=QG;,d]~CS{(Xaak6p@ 1r}.2,#'8(Lκ*dyK 1 ɢL>K: {B%z ganP>Zw%5n^`m[[f9Kז I.I̜Ȣs@,60(yӕ¬^" }[sʷh J:lWNFaxhn<099 {;Wf$w>dSi(=iصZO_،+O{#HlrQ ;tXkf֯AT0hfs&آb}=$էգK?E{axc,+.>WT֍Y%* KyZĽۙ.Ub#*耛0O[G;l0F |&kwo7 !5@|,.p@H dx h,6.pw|&;j'6z.3૚+TA1AgkA1fnΩEK^ P%u*~D$bLuО%$鰩kxR]KTqhDfQݨsYzDRJ32Gb~]+^DaW=my;erDrnζVfb/Eϔ_":ױp4 Deb-k\K_GK*C9kH(2Q^yԼqn҆ Pc;UͤB7RXش">1 NϷ?ҶH%cˢw21}7t+0?N+3`w4G@LL?lֆ$;+=>5iOvo^SQh+'2āpəo=l'=`K&~ \]Ң2e0IPIepa&>߅ch!"Fӿ<NS׏c:brУGt*R ΈAa ;[ĚTYQ9f%C<=>!$Ñi#}İRRޜHjXE1[A@BICtj{q/p ئY~Au%")Bͯ/Ӟ^Z+GI zW;tHV'fگ.nd̆'M0%Dy7Ppo,smb'$ kǖ\`ѵOq&Цldx""m۸DN OuΗzjȮ"Ԧ6t!v[]T>GF _&oax4C'vܽv O!Ԍ (a >`f(8i_^~Aݓt5reTBvOEJj$X%Z q ^x &%~|Cd81~Պ3rz5[/ szmy:&~kl4"Z2Dqr|A:;O0/;?r wL[Us__YϭK;>v;_-f @Q&a NO4_+ʁ%Ɗ/ %Nq58bNvp3+Y' ¢[ "kNPtdÇ9jt \2 Ju۩ap@~.N2i5m-o-LD(z.c"l1cjcQ36QAJ{O_-+E|bpjDsbʛ;)UI}*@fT$ND0aP-YVS?Mnjf m]gpn9Q!DSkɉUaw60h Fxs卑\> HI1t2C\@ c l|yĚYV&o,J@]NzDJ%NM1"c[D Q*Րu~!1u T6i6MQ6(%˳؜>.#G۹3ʚv@7Wߝmv ' K5KNbWy[,6LìNf%kw$qū^^N<fil[ÌLX滜 !4 6mѭ(yT'XP|dOd">΃u8)" @K1.f% Ry:HaJ>NOCx0ϯ-J)/guO:K# DX!Dwx]J:4%)u41ʓgCMS[yPo+MfzE?L&2"ޱJϜ~ZLF1Pӽt_p^swJI ې(o797G 5#ʷRQ(V7:5bA֪c-PݎaK\me@v;v'솾fSk1H2q< 1Ug: c>z#QxiZ )p=d#0sM (gZ&P}'FN 3k8Ȉo.U69ĩ85 jl.@zX8` F ML7!Rcr+%tp+8qqC}ʯ^,IhfKKؾ]HC 6 dSFC-R Z> &Gl ,@I0`b^Lt.&@Oif5r7Ys|7ʖ`[+I~ꊢGS=/%;Z ڕc0D_ 1s)sFa@E20@xܘUsi$!RoIs5Tl(*, C ~H@Y=VA̚fS|KWlmF&RanedA:t ND*Gޜ'N<~'TI{ vzLQN|ʶx7l橜u}PyT)c~y &L΁C-V CZ]4Z_ b(QUo(*N-g>+"5+ J5=JdcWiw}$?k+u rm~:@e(xÛqx9!xG}T.x$OIjϪ#!QTw{7r !F;wiC'쵦ܛEVeZpd(F kxpxzbpk*@g&Ic1qn0[1OSV< ݿ:dfI$T2aS<{ ˃&Qj.$8PGm(0o'SDgrbt+\>r6u_7~a%ꋸjZu;^/7o.9)K2#C>^_=i،PxGMoxTב+ga¾BN(=b;\@ N/>诱S#ź""qI"5U5cNH&YB٨LƯ:PvDwC>.)$C0x+LąyH dFѠ%ǣxS|UYi-(]B`eL+,EJ+U.&xSH'gpۏ6 }4<״ͫJԕ\FDҠ'Æ(xo j}Ɠ JG*F(=bL! `%?|֓Raz <JP2P̨:;d;NDPDG% ƈ|>3z2_&70n6K^Q^O6 G~ǩ nnEQ8RK~-x %V9DvA_ @&|cOI纏`08#\9k 6HV:V#3OH̗r-mbZ:NCmVAG@&D *IGŝ^s2@ h(xh=OcY_D Q%d5^G?y$}UUZm{] Z/HRN'{/s@ Y'It*sqw K?\ =;D`TOwԡeWuԍ^E`3 iާ-f"r= 1'8@8p4Y;9cV+rӓC'J_֓W E/Wq;_+vtDe*!bk^ l9DɉeЉEb08txΈȴon5lڙ̐Fs/}pFK)K`+OKIe`B@y_hǾj~rTBգl) 8[g)chZ@('M׍viGXG׎-y${Cx;6jwa[߽*xfEJR^mwc%:t36fnVGxu>a yГLrvw4/ 0/m~.٧zq`˥Tp@(UFEpe+fj4EN3jxcޥ FiACOV&NA#l:0a/Sʮy{ў!/Y^SLz)fרe] GJգ@.0DQNL.vnñ!E {qÛ+GM"Fku1a,M=V2z4H^.G0lI `*N,v H>Wu.}WKeJ{,0ZdKCC/J8HYg -P[ezyLL0YBra2,C02b[B\gs(ZD؝cM'LѸi۵Lr ز43i|7uɳp<+bh<)(qQ:!1[dKM{حZwclޠd1&q ^L wE=թNkX@=PiВpgݘ\9#j/!ZxRUBVaA2  =!z5:WYk]UR\le32p'鰥Feq(~T+.S_`Hv介cVa JR!;)x~A6KZHN 1Foh|Ä́JO#VTv{Vl\puӺ#fLjAͅœښs6(0A01e KkwTӇ}VU>¼qJY0딢~Wh(~`"Kn4ZDLRթd'k NwSMlՑL\; "4!k{pKGxHq| 3!4H~wh d᫝F;S:ʘɫoY_#n?O,>viOǁ8.hĕ h|HqpYQ^\q :ՙ]gNU][]8Y eȊ*4vjO:LP aθo㧡g`tI A!Rj&`Q5p بahu钼[`BfP!G)a6Ec\Gz[4Z:ceIZаZH~BZ]I pլCC娻3HFG׵meUTtN'$dl2GmOYdٌ@jzrL *[ 4E885n+ ՟ \D%DcKjObVEzdZn~?mqUoY\Q^CRQ^ |&Y; sDgC!Z%ҘG R@$|(}&uv`=X9hJa[ 0rJy#4&CMz W'maݔ8@/DsjО`3x&ӷ%XN1<p B(,"s6]GLWJW9 t=)7nwIPsEVz"7eNEUP#Ν}F?+ `e=Z <B+Jr8w 3$;ƸOF..zyG1OҞ!TcYYؤ5ӃKpvjN-U>vH/@)?lFJM4/^<ؽ*9RAu*zU%@؍``$dRÛn8d`i&+_N9vuYO_PFkI`OE/H;!:>e 癞\2vm:ZZ wfS WNLvy[DF:$@t@ٓ`y1牣:2=6gmнX]h/lAҢ&ɀpt' 3&m; q\H|1⑥6H\$nj\:)r"o@F q]oGh5m ÈOjP2X|B{G|0ǜ| rPٔ7~d gq,2з%(=xy:EՇ.2'iW:m3'q%[oBT,"捨2 3BDA${UDU =0ޘq)7PB+抣w_\5 늜PUs}'uL+jpʶXLiݍ6 i_p[Uwh˞YM`5~m!C`B߼:{KCn%y6V9ͦ.ud=R* c\y. 8f 81^Mn>uh,05koj\ dYT3'MYfIV/Hjq1U}/]^b/[F%kcxvQޮ$D/\dĿ p "UM~C$Seļ (m^M֊%ǿo{^f'o\Ƒ/TqYc ~Gtܞ[εcV_0b*M?2Xj*dh@Ҍ3(j6 Iĵ̯j= V'UXkT ZgGlv~7S˵`iX}7` NxRR}A}ݼo)LS=Kd3i78nah10ΒT\;A/hλT !? ϵj[zQp@#"y 1fg>cevnԒ hH|(e`X:-p:M2WT~m+X|m Ek2 :ݧZpF8di˪"Lä娸U5- lqu`pa4v[W/[nsyLwJϭzG("]w4X|Ư-"6!9hȅϭ,jWi|G8im&;Kfee|&x6݊:oG`?1*ntFrC"gj8ޕ)FaہPG!qQjmdRZO?xnppE/OVZᚴCC{2$g[B}!L֒5lyK퍬fECAeot%ܿ&{~qϱ+w'iPg6=kxſ*eZjlDC$s!V 2G<<>kFtQ,x&o'%"kvԬ򰬨\ 0X*wE`7Hu.SXsl7u3-v oISf2s'ILtɺmd p7dI-+ ŷn> 6i?mmQѐ-J;+ =9|6 'Xu#yn!-TV&g_NV%Ҏ\t֪A.H[MJm<+-CAm>bhfH՝)Y}UL s6hڢ~ˆP EH 7T`1>1t"XJ=\;Fj#I{7aY#$#7y`;\oXuWבF~>z*G0KȈ 멣gA[(X PU:WD)\3Q艦P$fH j@\УsWsխֻ(:ƪϊ?<Mij\#Nn!``W!Lb<.'BN,?@^K;6-*XnԿOo^g2NxFUb8pH3'N"3{Q8AM!.$5F"ɝ9HO\vk]bڋ?-$]Rr(>^12yx6N]7l=vX%`!:N6S!bE-!iAoN̕I < l9Y해ϢӘ B1Jp:%iCK1Q`:x q) ?1'yCSs1f \.o5y6/0i''5=u*2OŎpLw8,c}E ~vLG@ir9,䦼4-W/$!z֦Ի0GZuCM-:|·Cq,)E㱵,`C_o;/0BŞt6>*K=ﳇ}g;/i| #n-7pʻ`xӽ&F=Ƨz1ڭjo3y4ӵ?(T_Lӏjz𤋮jp|{ ,vIHxvECl]ٽ6Ui\lsr\L ps@uE3wZ-P'%/1z33ێ}n@7o;$TR W#r}$\4w+fݳ޽?pXb[~aASf)?hfpF?{sF4V!^F5Xؔ22zBxVD )wsaůXZiz(Upo XcCdOqxC;-ur-PY+\ADDa(J5hNㆣ0ȨFȜ/gG7oqd]2cһm]Xכ\Xýɜ@u~h 58HIIE&vuzBch|H/Z4֍ϻ8z:7i"r|Õ`_=,)Pr!JHLW, ɑh &oE)݃.d;8\Ci2ȗQ_# _hRV3=jm3R=•%ÞJjT%[ !ؒP%pN@ 3CiTAQ̒_Txx`aK"nVp!TC]6LhD?ҭohs'E !\M˵8v3ٞR7duR`ŵ[Q1%6E#ϱC-)Ke?rhI5QAk kn {Z|4#b"_EkjH/H6.j52{O6ssƔ&.Gd(%33"?ܖK!=i(y/6RK]͹Yϩ4`]gk3 &]5`~B8þ@ @@X.Ɍk1Iq$5Z)F R)V/1`?VZppoN΋~U)DJ qh8 HCt1f b :4L$ip'hM:$!R 18G&"=J->O*Ub%WbTTʻ^p>lI$ͺ姗_b fdYD^(۽Pׁ8>!r:Hss38Z] }^ %!7(ʴS!vF,|oD8ߺ.,T(0x~Оuze%n3L[5kUÅss2!{]D4 @QY}>.i.rQnO5,*P/\a]Ŗ6CrxIo;2^kTTYBb+ ]~*o{ _bg[/0zWl8S4Ԛd"獭6y}<tg A1lC'dI N1i"L;oj52h@1U5ݓC j6 w軨|,A ^)PT, 9hCDD<-[m6M(e@j;d(F0n Zbu+x_YjF;1vQ_Wm˫xI4Dp*/)y2t\)ܶR-Q-f/c-a)0ɰ&U FpZñ\@;dj[< e 8wR]d ,mda螥>i' Yd#n@@>)c6TݞڥY:q+ ,[[H4_p#)0 M,f"vkPV֌׺f^ʰ5=wed-Ohw,.w'WY*Clp-iDftv^'<uSXI.=w8= 2hvܱݸ.Uel}wQL b6a.n葞!Q7'-l9dT 9Qn8_M "`|/{}ȳh@Y*@|PTWA1ѓћKS^_-)h&O E#[C,gJ[*cb6TpLnb+ҩ5աwc6zDAYiNa~lla !d3KGB ѱY6OS)~+h~-/ b?ICA'b;:*G+:KWKp$$3YRM2U2(=zp.bV0dN45ߑMf˞FQ'Y[ xot7<̀Ӗ~6qz7Kߢ1{Toܵ]4Ҟܕ23ar\0 ͧu%vjҏNE.vi C8 nx qYowlYvô ;vL׫nu\Z̋9b V }@tT&QP Cڃ*9Ϋvf:28]n0DޚTS, )Wm?ks09z] k"Xi^qUzz~I~׽VѬ08~*VeCnK9xn!cb<#9qwVv‘-klهjtBD. 2p^YR1+mwx((A>](lB\8ol̞fdŐyثG zzG˥0U:Jht)L䑣mAlK+OEf4W[&v#&IGK[sK8ɏ!`Hy3P(LL|'9KM{f ]Ɗ+_%'?ᐃ~%?+JE${LrL%@,?[ 飓É&fgDT{6FGO ;7j&A)QZ%\SQ8n%C$N 5VZ~f+'5 #Qd=C-Î*4Nlae9;*Qw\V^!|avcN@roo)TkOIk@w=4KXfTvo zaY+dnLYr5fc?5AfI:;qJŻ!Ua,̖-gPϿUIv.d:I=9RR&6{&>&6qPMWqtǵ8T}B|#O Ǔ tV4ڼK1ۘm3%PJIFՎH={MIJ rZ鲩; ]BZ3X3TB+iVcX{c^'SG\W&zb e?-KT_ v)44w栆;i,iZty9)VoܼfD_竽҅o?tǸDCV 6ސD ൤o~en(ÝH (? Ҕ5마eat7L8zXR5zF k~+R%׌PlH1 )i%c#u bFz9!(D?HMdH6mdC["9@jANdPEysGūguȿ+C'$)iB`UhT7މT1y (=Hs<{a{ǫz?>PLMųۜ)1Om!1z! y+10RJ,zJO!Q%b96 w rvCqy_ =3ȍ؜G >MXYQy> -t&ݝ:CSp%a{^dukMQKRQC7`N">6a3w4 زa؈ hGURpF/ EDD<Qszxd4puvyo\qYq'#qW6-Xk,a.NL!sg {:ԏ )S|']Ov]6!-v>ȵ,{|R(g>r*ƘOfvC~opT62Zx*4⤓rRfPxjuf:;vmFYP^q-(ŀ"բUmy "X3eM˾ jXo퓖Bt< F*zu+=,uW5% _9DzSh3oFY|aF{"E;VTG~\.Y}ŶH8TuԪ*bX Wqr۲5I4,W|\l2̠a>!TW8`b\x!R΍v6S[IamUmq8?*LE~煽f@ Fl?<=Q2Mf#c#=7mI9`)͑VRo;}U\qcPÊ!E ɐb>l!Ta44a iqGr-͔/*d2cOùa޲ݰ130%#^~ՕM7nv;Cc'L}iJOKAbGèr%\y(;^Uxocr\}Ԯbُi^^{Fzͼ|QEp>'W:xEdt ≐láFv ?/=/9Y;RqvM]=i}]PS XK.CH/-`U@e=cԌf'D A^>P+gL!I ~ I;>dse Xc;iIwZ8{psUJ~C+8r삾z$˭ =JQff`oGZ45C$h&uf KS-$D3пG5߯͑D'{ʥen9 Ԛ?𠺐4]3cyPknSߜn@i=4O0vGXj!2*OUW4s|zw4i|0FB2P`= e a[t|mJ B-C!35ʘpxK5Hdm<*>l>\Mu2A^I}t kpi i,8}vwuFԃQf`P.pCz*I;i/Ħ`xP7!UVE0TϷ ;[_NX%&o]u/[:T{|gRtdܖ^NЄ7hoRb [/p>Lf>!U6T rLBHL8޲A?2>sG1ONt@nu^l͔q LtwbMkDhU(5Аt > 0/|)nlա';~a')!Y[~u?mr!)Iӳ=p?JdZc~o)Fa*hCɟ̪;YOT&Ɵ:}ҟ~RD P/GBS6\pOBpՌsQq0 ͢i@|{@$j]W -EMtL)ays7TIQ"YݽAH}Zvi2v21!6cP{:5)}>oHqFoխ7ZZ~I#4wq)A",GY{$#-]촕x,P–HNk}QT3zsL4f4KS^ M2AA,ɚMZ;cKK@&BXN-6.T GI#y>f{mTΖj\wRm;kw3v%6MFΜC(UOQXe*" os?e6z05pr+Wr0S{kR{d9?E{Y# mDIډ Ҏf@B7rUⲂ;<𹬱fdՄR /:`%)1 ^wyWO%os|WȢL]`NJY@M#Gh;>&~688L㬜lp6|q-mX8Qt#ν,tKY&[q HH LZshA wudQJ- lAA},< v9 +GW'15ͮ?n|NH{%nT?]3)t ΰ[+&3&NPd͂JBTmˍ<͛QD>hMn,!}&^qB=ޫftKzV0hP D :|H. 0M}p6[DA#^€w! ,DUpd} >kqr}/[8}]έP VOt+^x0\)5c: x^K"\˔Hf"׸)#גn7 v0o7ٴ'|Y,+.QƁ(U|%2$1iaݤfv7TMhႂ[]E(Ẋ",4$MM>Kf JM P7F6OImsPȈ=dc.f-sS"DcEy';UA5 ̾"5fRT=nkfHF "$tN3ß;RK43d/s[!EqdEb*8'@ ɤvWz#o?7՘IՊ_INhXU}l#7gyj2b9̬}kGKiY9PhDJ W05I& 2hp᭮z' f 1pd<*)Fv&]WkVc(Ӫ#\{O~g3"X;ZUӠz0 q;3d3И4[%3P"t3׆j[j}WTgg:;_=nLo3_*8Wdӡii- 9jYqTsaLC'_382ؗMqqwQn^P+68[羴F{d/axtHc@}Swi[$U#)7ocq\.QsluT.zScnw 5\@oϔɰs6"/7X,-4F*t>&3wvs,Qb~Sq)7(<=ek͛9qvD<*>6l/F܆(*]GH~_4!f,Ѝ-{o_zcWmKGejlY,&ٗ莯f",7䄪ec#(pث?V *9eR~J`^u+ gX AlfmWdYIGkm3s9vt l:Uy8M~tz #δ?^*bB\X vPOP!4:k0X?d9̈́S0/hjLxUiDb)}_㸂-k~,&̓-9j4QA8&S4`]ۛIi"8=zω`X̠NhVdUHV{|Bp·~\FPF! L E=PyZ5'zQBTuheİ|ed録ij(ҨJOѸ4S)lQHDޔ| R#벯M7W`Z$<>FD$haNB p7HCcΛ{жv'D fRмq~-}m ;,.nͦ8&F+V(m2"ܕl›p%N<;uU1F+tr=q^uyAG 2`CdrXvP?}ZQPyM,# tdfbJ4 2AFeF DB dt]ٝ˥u"l'Wm'"ĔvYJwryǪ,8,!E\"%{vqF`b)ED!2h w*UF=3@#/q0V>w`lWO+x@סt.aM@miH~C0=I5?9V{Y5iS9-:t20 N䷢ y* ulLjrG1/hN;mgvg#i- o-ɺlwc.Qx5-WW Sb¬W][8+^͖!輦"L-om?K*ܕ9IkUPpdp.#1(A岬s&|9sw uaJY JfSe, ۘWbFNϏj{!:ǑHl'" zo9`J.?$gԥ/(Uޤ⭎-8؍nGC5 ?[g,Dp uDOL ,43HbSccpb6]=꜑;p?25;vsW@U -u  8"Ai#Mu"Ԫ&O?7נZY-/fU(x Kb>@yfªY]ָj|P3}3~kHy[e6v~'Fh| wiTľ8U| ttq`RK:EZtkBؗ`M A[Hu4[bgyk~(,_k+Օs4bGzB2lIU qp-BPE3HNnЩeL rt#9l$Ru в^`TɆIwZ*}W!)Q!SхP~,PKUiMcj?]\# p׆S_bgA<#+4ieԚ|%#l]sKb1=6JPHll}"ڸG7I1DzKu'|R래xHC1|-;}".L`߬'/Yէ{xD _Os siaA/S| Jo M@6Q#I"#?wy98os2F-Tw"O /mT6& Q أ͢sd`M82SBd5<^1TZfeBO R "Tm:Nn(A#̫n}OUMLϋy$k@QB7-'do^^PĹl y{AZ۷e/qOŋFM,Mc E/(|O>NPTx؊QoW`ps}a!dւ;؝鬒hYj7|{3D.{WxCM: j!Byha8Pp"G_fv8tJ'{*INЎ&f;2$W{x|i/z笮7W)(cC2Δ0H3O\^9]lA*S&xt饐cHQM q9?!FqD'=A& p rmp)n*]CZFv$|Vuor#G٪1 t7&Ve=vl$IPZ %A?eVj֩)cP \,/^7L_SrCh+v"њ"1gxR*.n&9r=/gn^lb'M ݢNΩRXy3n>팅՗XZ} MA8(5".mMJg"aP5}H-/RBps6Izu:o&|ZV=}B!^~Xo P /0y-'Ohn"`ɠqgl7g elw$G=D'\&5"w, l,)ƛKG'UuMmXTQ:۪Ke5JicC*E=?vSu5[P${H;1TQ"}&j=ЀUr*G4qy!Qx%AbH¦$9j%kmyl? xb Rj V%jJUkCCX.-$qA#n <_^p^BA@x6/ԇw+)]g! ' AۄߎRU?i pߓь U(άAٺH[M% )emed9IM:3"hw`*Μ^F޳ׄ%C뀿::n}Zz6X8+5nM5ܸ_:9i3P]C&D (M8OI/X%[aFW#pU Rsw6nL &-yF.PXQ'5Xw4PB:tě5/pb PwQIl45A:I Hѝ /74*{ewֈRg+K1I dfw Hj,>,}'!Ony%c^˫޶M/J/l`w:2݉wTRo[NJ"6?;WIn{؍_k"XwJ[H^0JN)M{V%Z÷Ә9l RL MU@a5ƿFrHO">mXFIZN>AZ1L, x3l %ut' ݡ m+R>u0b'EaIVcX-ry`:u?VSW<֤6n-k\:V9!HϠվ~k-_'AYP@iu n\H9GEvbF+̝" F;(l$'ñt.Ҥbh!k+jЃ??qwG]F)3 r [bОb6׀ *9 d#[dj;ba uOH| ^_nRviQ54>g0rY9Pv!8 Li &ql7נiGt̮ x-{F0]ByX:Q4ŠLt%B"Ajp]gZv~VG^gQ@AޟY%$aեkMe`&'xє {W2,\z^a:y}ys<j7@h+8LExe!v/Ҍfd\q}s3j=jMU$ 2>]փ[ʲMiw:`I @]r9}T$**7 D}k[*%? 8lgT({^/6.NˆnY.޹SyKCRDGE"F$T{h&V>a5oP]U( r۶A?Tݔ[mpJ/-?#;[Ib/]˷^H+C# 6}I#hL{>zDòig [!reNDϾv+U|Blov'B :)ޟ!Dg!>H΄n~VIQHǑHÐ"BeBmfhFLFBlKV{h4ztҕ 㟷p2voE zGo;<@{H4nN $/ KE51 ށ)6Q/6JRp@,#zYw0 EJAc^{,'[gڕ5싆by0Wi.֣ ʿh$4Jٶy~>_]ȋ4N_ek󰌠ly=5ӯხTI$MWjU]7.{G3)T!J7 ˆ!J@Kd]Rpi8̣ Bn)bv*I! -LYfn?T`͋ʩrsz̞$)!)S}[t]Y[O@~ʟ '0})2a=1Keq$7K &ßkgI:z+LEvd(OMxUX@SO%5%t~Rɓ#HFc-Gpw+BnxЩ>T|YEaYE=!0{f;A}5Q-h1 `ċ%?0 Ea(z0{v9`vU4r>[ 0X8v_ ~˚KOOq IPXWa X;sS! fwEt)JMB\Y_N-;c@m+^Lܠ$vq|Hvs 'ua$'OTm:,Cv7lq RtP"~85[6܅;96Y*B}`!@~c?M;;_aVa$kGX)8vThpg~*T־6fF#nO"T⢢Nz 3on@M:~_l5|;'{=<tAY )٩08:Z/- FH-M Խs=_)`ƱW!f->wvaV#3}85`.vOA0{IkDG[$s;7AξЦ3gϗbZCXձjQ n2V+Ô~JFxݏslRĿ]sq[lVqx h\/6(|]ddG{瑚ehHAKh$Crƻŗ!WQ$Ǥ k0^1t4Nx$M6gTvmhٺ {!Ef="ڮC[kNBDS'Y9y$ ҦwkF;zY `dus9DЖImhd"BK"- NEmj]KE`Jf#@Mw&5z&G}e.fjhTwH?c?vܬa'GsΚ*-Oz;(]W\o'hI9T{KW\TcVyER>=Bt_`>0[**UD.GHVEj 10ߺYXyDNt&wKug#wkӃoB=J&^SR3/:N1I: CQ 5Ӣ_&>+>~Kޕvx<G&Sdo4Dr9p`x۾QQi iYm0QtGJT&KDk1B0GT{ ^ TP +Jn&77i.Т7uTI"pO)+ۿxǜ)n"k _#]v|H2o+ w#r7xvؗF|i|JZOy!EI[=SJ{'$A [NѼ$gI2b5Q]x{uqa #rp]ĞDr-N5D:,v4h&wUuT pA/G*k+y`ljkur -^U"R~*CIR f'ȟxe׈S<$Kn%#~"*," <@G ]oI|=,PKz<(XL~~yCG':<#ì=bR#.{"2Hz SKG8Uԯ@GC0ƣX/|FRoD]{)qf:T% \Ub\4FRݸb%IXLRPm%=H$"`F7)HOl/!>Nڤ+&jaȯʤZZ!"+ST~E?2 z֮7$-kDå-h Dkۼc9okB\Vx108x5EŽ=]A)hs4g@\5k-ZT AFP=5F؛[7ieODL7 gZ}X>o}jsnuF >)Mi4Ea}rm+قdtuF7Z$>UB7Uw5Ѫ}1Y!>K?.N8 #KK=) !L3Hq1ⅱSqB%/&`Nq:S`?q!ȵʪ=+!8m胝h K~E>bŰFXH䓋=)rq%vŒ'S}nWƩy)f4e?a MA 4(YIks =DDGHv,M&?bs^;w7ɏVC Qѳ2)~OCi(6 RǞoatm~M6ëN\Zb/%D2F0n2?7?9UyIVXdi;.9z9S?JspM@UP9XBrL!p LjWY3JGcq{v+B֞]O-R@PWOw<˳Ґ[D.-f/r3XUιU #53 )!Ԯ4n}<,]EEh<)YNv_I"U]mpuE[%2u3(+d+F:YyG;L:2mD<[Ǝi B5jD%eΠB`N?Ҕo 1/z^#Es,ak~b9bލ6TiOsVJLtƍؕPfhR#!^!^Ж@I(Jruo*/3:Ihs8\KȯU8!xO f1+2p/`Ēsm偂?uiH \%=_G(~<,*׼n6]=DnK,쁀|^u/(Z͋wZwVVzzqd[fa RuBiDpz\/ Bޅm5|Mչnw/t\+9jCʹ_Y/wjtjvBHNA]8 uB/@3=1_H;nX7VmmLKQDe΂P9a驈&2Y)\G )-`o$4бl Ŗۘ>;J/ 3䀔 O2SWjm۷pVכ6c- 6R S!zM6(tN^؍ d%qE&9ُ^iV[lt$Z&#l {jX֍dȍ+jDS631o_`}ܛ xO frY0 ԶyGpas*X.0GͣK#$MBUt'N!Y3FZu).M.afazCC&5t( 7^OӎDbې8Ҭز4cnĄ="uve3Kai<֔M$ WzyU1r5+OQ͹lܽ#`Q.Q@i s ü-Y;N6I:T02TDh*H-p:3Qدgɐm֔6D1;񷴬ʊd<ը$}4! )ށ 藣k^=qZԦaaSKe8 z Z8v)!::0n) tl JJ˚vHg {}( |eD]Ce#ETʤ dZPw83ڹ1p"sTwl>\ޭ8cYe&qMzu!l&2W1wYȫKwe6uw-ٹގ٩@b;L " xكzЦw6S#;JZ n-)[&|| գDv͌U |3t1@Ŕ$y=H-ܺqp2Y6(".dltQꡉ"UƖ~@15W]?Dfg q2nEύu;S A1 "]oZ.Qhнu[ рnUp-""3( S~cV3>_oUd3Maao1}_hŰOohD ueA8G,x<_Ϋ*֪AWhyΖH2d o)Ͱ"=q8͗-gql(C60aJV0f 6ŗf;z-EF˨2zIr+ԕq0Di7oXgء{Fzdقf\DLӖܨ3"lI`]NŶXo,siD$s&T)gSLd3B@Wd%5`dF@-mX>Ӯחf:_=B/-e#Cr7g{p&e_^I>k7Aj.I}ʄ fǹ))ePÑ8CuΓ ȨFyIA$UX^T^)ܹ9>wۜ4Vg*0X];'hPy?^x?O& b7Z,lXJI!fU GlO,(yHRTugb)IȂYPg=mD82LIRn:-|WWAkpAHGpeS %N0a&6Q{`o7Y,dHmV#9 vQ.Bn.ZNOq9 d-^roۛ˳y3A :{\Uŕ%aV6gyO==1(~ r9`] F$ *aE ukT푳\sl+R]~+fA4=křBLD}0Ne~L$օ+!L#>_"gB<b~4eztL2y1@I5C2Q>ٳGrG~(Hjlf]ǡ3dg4O{?Q Y kA ?ufF[gc 'ri_p;[)--&xp5ܒ3O2j/#v +@|DQ)Ttb~ k9ۮ}G Ȥ'5Fn.Y͆Qq}#k\?a$Dx!EMϞ4>Q2:BolA2NXdnsB;ۏoL[T8k5q6ɎW'*)czΰF:A/B2fҴ5^[\59h8MmX)(wb=}N@% vdiS< QlS!6R*sʹ2v#bo=%~ 2A)Ma O*YoCā1N[;tu"[g.:f$CH`D|e3a+d}~GC$"Gf!hy{Й(lcUB@iIy]$>Iݫ\F׾AFlQ6jEʯ ȿA䦾ܟ鮕V?l-a}g}ʆT㖓ZTؾڕ̩q(m_Via@*CK!~J)/?0.2MvTc]A@NWR|ݺѝ~e՞[ò{*Cg$cl#7*ᝁ#;":Yxljeֺz!-HR*@T!$EyHMb=\(IsypD]:Wl>Go)ZucwO? q"n9N)LCp"<4za;A&8X%{1n^dp[rVbWKK?q:^sBa!+Nldgm(16$XǬs7:9hVu3<:u9?&"kʊ.Nb{xArݛAn׳K!'%4"G[W' :1}FC,nIsb}fM1Rhإ, [8G 5?by-L440=6NS 'DnMʀ:f©|LԹ=tdAHԚyf4T=m\m}Xc88dMz04Q,*3ÕeQ\x3wvB{oݏ^ ]h&y7xz7%N"+`"5~Z(G/_)#[9 \#b)0'bgUEڲ&ی]m3+Ӓ?5w?+x WN<蚊cʯ@b3K)}DO3 S!d-X鉌I?%3'E;jPAee*zI/ !Ҹ􍱦Ngpk"++ٱ4T7(*g T~{B@P^RRe_gz{b߰%#k<&'C"E mSp_,9Pbv7 ΌHK+}S.\rm=;}o+q"U6:_yZ7wkhXi+p$'ª*St.'?JgAcvDrm5G疮}&QbŁ̇i-XZIE(˝)Mp(l4;%7H{]?L/۽ +mP0QIU%(3t'LEil;C4:.P6.\UJnj62.nmƵHp2"FX}VҒYHD1qސA̋nuza-d/fB':PGf0:KryAW\R.5MwV QFk?'ȣUA%XFR,& y-*kV|lbw ڔ[fmWqsۏm 'EH/Ȋvi Lǚdw[|RX=ʯJkx>G=YAXX0D#?ZL % ѓBByO7`G5) b;~"C_K^긶=  do,:~2vuܷ$;3\q@ƋΏ=Z1/}(o cD1Wi҂X| r ߄Kx5%8FuPomCe2W%H=diKdKc9Ƶ7/+A3 Lfdbs;KD^1Qō6,9U~>TJ6`*}ae85 <܇RgRZ6<4@IٖPڴs"7BLMYҝ Dکh|h +Y!6*ӱUwyNi9$(4FEnJwדf> bⱶ AMV 6oO&"kA/4v7?Ns?8K8xw s0|hjtRK4//t~)JHu jX9/یC Asg>\w@NdpMe u(sͻ|^Ga'u8!XU~}3TCʆ4,˰|6<F'疒)Vkn(‰̇t0S[xR%x}lƾӤXi;qeERŸΫA2EeO A[ P6M-_#,4sHT}^=28--T@I3wF sM?$k~ <{ԨR[|FŜnq4/OߠbU4*RA KYPaJli8PfH-+˥4B,ϱb)tP{ʭ&WVЮqC[ jߠmOps.>T4AGwXҒ]X;-45/ƇrR'rqg|'yM)uhf +QKG K=>Hjw֌B ֫9+qAp%*뻚 Frʴ2@ A־$ =dCJ;E1mޟz5׸vtD,Qy-NpOmڸ(fhZAi4A@wݳ⊋XⲼBB9t8hdj(8&l|FS۠vKqലM_pZsP1j=;q7KMSQKQuY5ӕ,NbP _[e~4TV]GMÈqwUȔȶx슈j]ڬȱZz"s [~}+?v'}ӓq˜ÙDDY;hK_;-eBd.\(vB'ZI"Za.o.i~3Oä:urH}M`H<ܢ"TC/ůK>2ro ;|JY+ѕgS9`jn/MD7l)K*Z8,%oY# è#lL<$lqhpt5`_DO<Ve?x5تT ƙ{d gp40z 9<`we 7(eI}#s7{AEV Wv$pּ.ziIY6UT&lYR!MnΝA='rxYgo9j k/j(sZ}fmtM”j\1Ӱ"Xu '<o̗ʹ6B(V*^B6oVAW^J٧T#V6cI GF:T5(Ba+LfuD٦x~ 9 :ԋ[ZaǬC%wV*&O2x#3ĥY湽 J+K S߽؎^"_ `@tZ䯁 {/p& %b֞u$&܇?{ΎWl!^H䶞xYlR mQΜaܸ gOtֈ/n5՚2bhI%"=YX\ya8 2OWrVg<{L!="s3 ?TdəWeS}_KIمٱO3Ɵ2h2G?l#ٓ<ԋzDkdXvǵ\`74H$- ꄝ Z(!p1ey8߷S&!hwC|rq=mN3"H[$)%CpofWs[ v/oH'!$m00G7 0̆!Bn5y%;D}WO>Xt輿'dl)_Cz?T!9=\P!6\<:VM>䏓}O8'tEfdw[(uCC ]KO7L 4m2U.%Dݯ3|^ ,i8 t·y~tѿ/ь6(RXz99Y;Elӿu}>5RL?twuh'hUzl]Wdlm^D.J9F`0x|n820/yR,0 w8 Џj/jٸ#UU3O/c~yAgCцt1IhCN>pKn qsEi\]C*wܻdHWBԬP ^@rLX1a,ۍVѰpFFxSu:MaĒ8imcUA}O(.;?Qڱ;NoqSgs+cKx@ha:n\?}P]2,G>Xv5$kY _"%m$J@m4*S!꬈ƪp_'o}͝SY+!@5!)Bio}-m 7c{JZTSlQf(N<;XdaȆ /ЏFx+8Q c~v\xݛC,ė jV.hdLQUT򟇿KA\ƨ}vKdaȏ #t|bSS\T 8g`x]KA%lPKD?Qd "$8pCsrU  5lvݙi2*}A2g| 2w[j4nV:N~Ӌ])U<]ӳm=$~[(Zt'6<%n{Pk"(2O+ @e֤T /vr1KFBe]=Si~Ti!{IVN]1;8\_!Rs*rǾ:} r~M5z$ ^ F#:K=A;[-W'xBm-&$eCz+M7Ğyˀt+g䷉Ҝ޽;  <9PUBorb~`?>軺EծH5c9wpt2yʭ|Wi(|3X”1x=<$G= ^d iu_eqW2ZNP9:mhFiI*fԁ$BJ]#e]Gڽ*vU|!Gb<Ҭ'Ԝ#ݒu3QZ`KdBNCgxy  v?Fet>-˥]B'ԭJe9%At=*0I讝}\WF9/`ݶ MM=)kИ =IhF}.P.t>>@JM\|4ԚYkw w 0THiC7jo&n4S*vIb^ڥl_ H0r糀d74[ܛ-I1؁xDW ̄ ˃ duYoǯ9KbY8*#,6]]@FyTJr:Q ^!bwXuP~>$ć}Y7Hdhᶱ &;} ɕV)& ~^N6j(:8c K6T1:c"3dnc7 Sǒ'3 -|߭"MFA``nIl lLWjL`]T.E6AdGqri8 ϯ˺=b%+|Cč /@% YAj4B_!r F$F?٢)hz4~x#O++)d jEtJ)9[\7Ol{tP+xd-g#\n.4+6fGs3R,5+ve:oj> F˺Kd2P$?5ʅS5F#8v@'PZ-WգGMEPczsky0H0D^ _n񞪧f59<贄s"~VL6cf| =#$i ߼BJEݶLɿ~ JrGT[G9.rt:, uU@rtɪ ^Ⱔp6N`HA ߸SϪv qX /Yl끸8m izHo0 =4}كᄋtTC<3"*?Kr'Bj>T.[D ͼ~L EDO|RrK/W'党mϛ]Ʈ3X m1`z:'XK34e;RqNu](ӨOX>4vf&gZOӬ0)A?ب9ߌ$26"^? \bd|nݱ0zjkڅ0$[LAꝃxyaV?;L#[VD" &GrhVnQ߀ XD0}4|tO^%a,̄& C3`kVuV5V52-S]NxwuXЦ {oST?Ckˬo[퓮Gɭׇxud4z"zR 1,n_Y pkآ͋*Բ"@)8!Lh@9W"@F%K*I#G#/ "ޞ~4:Ւ/Su*Nۮx,` *>Š9,^%ĘtOP@W X]`ذz qE%4"sS훃ÈYcPBz*$CX'Y}]uaCݭ1g9p3*:[pZ^WB0Q1&*R69%-y kbnK>4Uq>TΪq0v x*;\ba/\APV[C9'" y* s`);<=*$%.6З weneڇtc@] tT*O) '\cmIާXD ƓIeSA|'RD@=NZc{ |~LPRֶ+xZ4p"mF}3b>E |B)`TB[A免JPz6B7"(M3B[e-@ޠ2# KUB'_$ ;ZW&`xoW4}6ȚV Z NQ{(g*>,2v 8k:0 ꯇț Vħĉ>E91!gGeCY[s\%pP0Ft fSGk{/cgSںN³雙4La=MEQ]2?K3*{Tۇ업cA=E8IwXE)T{B'lhNL+Q@1Έ,G{]`UW xz_ .g+m̬n;Y3ހw.TH`Nl\{]v3v6=~<Ѐs6mnvΈG>S (]gZ5UB|`}*~HNC,ӒP0gnӋkXBB'ΑiYIq0^^ҋI }bEhi |L yjQg<{ߕ  o1-J-A5 򰎘 d"/鸝lrF7ۼ_ H1ʗ'U4t}uv| ^<$}#U9QZ6W39^.,x5OBUS ZTf~}XSe0E7Wܫ.7ZmsS.foj9ЙV@t׾ @^JywX祡/][mͫrxDf0[MŒ]R&Z,Ii`yyR"xz'ݳχYD ZJ sk[_ )T:ϑb/V |8c^bZ؀Bf6ْ}$p>h6ݼnr/Fbq4\H#%Hf=oRCcel3_H=\YM._/7$oz56o_MN xHJ\̠$ \c[~@ެwl&U惵U Xx+6R`ubbPlz06o-rT*y`39Rkl}v:i5s,ősD ڱl .sNq%Pa6H<.EBdh `}b)!9Y 39F MJВP9TC1Cn;;Pmа&sFgƸRt"RbMMuA-#u4kgTH({V Ձ{_'eNXfᰬnpP6u\0Ѐ%fb44: ,Ji]{,o~ P) ro=0dK!H,ʑ>|v,ScMG{ ^ǜ0,) u9ė㸧ra: ̬7{!:fd ژ`dbTpQuLh=Ճm 7<2Y`iM+u IW/'{,Z"j/c`CJB^@\@؉qJpO5*g,b?ꌇgz2M X\뜽VuY,J~rDs+HQZg?&B֓Z5yihNVٽgaL_:o4Ɛz tRlyThAG Ô{Q-g"=u@j1O*!nO]Gp z_VLy"+80+N4*PUlV%S1udK.*WRF5Xa" 5_^ZKPy_/+ O}&_.vVۀѠa(^ҕ--d^r\'b|9=avaN5DB)?DO-OlhS=bi n#$ h=\@:s K)]V|]t*8p%3E=-\ly0(ڞ`WT4  _RL߳e8:f`lSk b|1s<ļk4Tc,(BNY@7r:s>3 GeX4xiKSYmKu[S \^e@JBI6:^N YyQw>H!z5ߗO5aOܨe}ދQA?QNӐf0Ў`~R8!Ի1,hat6:{5=7{>bɷ2f֛>h,`Z- )w^j?XqT:Κl&7+Ew^C-) AS_|%ŜDG/rzn@Qű./E>w<ü2ܫ 6]4UEػwBC$ wd}GNtnKYDL(e4 -tir3{&X$_k;zJ e]CBd侒 7V"Qf[1ds"ĵKz&lSF޵#\JcɏK% &ӷ}"06_1qRUMԍف2#5.:6IWov(KU6--\?a*5s,#Eh-cqS:l+i[BG ma71y|23_zII'z@8mTl5eMv;3%KVfKoY Wòɭ xW\uv卤͉ ]fGQ*DO}ኙXf LL>j%}K\oF-B?=K)53=ܽCM%Z_DCˤ+>|0 L#PjN1 }DF 6$l`\ E5G= 2[,%y,w`g@ycJ,\_~Av \%;h;#̞ U\a3{]dorjY?J2;εzY[Iu2o=jGwR@FEح૨fkԁt&XcYx`1;{aA %~+/,9)awP1ӏdٸ<-!FJHx(6e.P!i 8IwQHA'AD+Q edtq!>3'n}+` Fxa';f-IjKA2;{?MS~Ik }ά]r202cR!Avd%d:YfT45 c k'ży1KmM(.pt1i]}uZztIQIaih^ ˸#Rx%'-jծLa68)Vh5<(*L L`l0V>XE9ϺF:5zlxIV΅d(}'f굣~&4;l[L _^\wМcU,r/1ߊkrelX ڧ[ërl(`{?>Vc+9PJ4cqTǕO㹸 1, 78rjNK-iYIo *EVǪ jXRںKT$XaBqtII;d!+<~E)&݆xe(SxEU.Ar;!78? 2Q) y'()?YhE((PfحE7),aiA7u17|դ׹R^R7LC`b.hzrŐ@.8σhŞGUAlWN&,.샋*!s"5slnB^xRdQvvtjc~@AϬgs1)4@Wد~BXS,Ὲ<>&A) V>afߣ<u Fii͸tj* -/u<ЙD f'3ĄYTl݊S8Df {[:J-d+[Xd\`/nL8ֶ6 +=LG 1F1d c擪@+e2L4+Qͥ uѧϔJ+w#1G=5X~aoD e 'ohvvۭK57'&FjPձ.'4Mv=(x9?{̈:uO䝆 ="ԅ0Cj|ɃP=3Rx(Y :$%|m6: 7ơ1uCT5: F[R[5g?/Y?w- :n:!7:%1%.=Azhf*pfZ1Fʀ\0U1ϒ%Cb6bvoPLԡ1Mn3nv酄jw.sl)˜WM''b #FJ]H}k"A^5Ht$v%m9lmKV?VV#OFLFU#9pV;dԧّ8 :aIi|G8d(j2DЋ#ܐ;COˎ.v5d#ZMJ&QQCQ,}7BR,0*ir3勊, nѕ'*\$v QݺCދeU ~ԴvugUdZ‹_a?Us NHa}bĥ- n}"wbRfp;UHcBŗRh[թ)Z%4c}ps'v{@!gNv'S=!>0-LB Lj9^Fu|$@>,/Cm N.ʧsiXbh`7Ы$@ ^D!FF@Sb|ҭ@tO6\Kn0sZe l%l\q"at a͖kDrwat t` d]9Q7=j--b?S9VcS}> h>ahK(jF~YG^1vWY[BԷ8mq1B@&/R+3P1۳nosT0<ˠp=̊ɈԝE" SxU-$-Wl" 7"B7al?6|ɖD#[!ySELRO@Wڢʇ=mYf-x>e?R0cX ,FY^:+Ij;e#b4TPqi?VC>'y#fproޅk0}{3,hAcOV!5B}c8G ?=֞5 xG&v~hȆ~tU9Mc~q2l45AFoL*F#914pLuҜ'N@%Gqܜ6?3U"f7%4֕ 8ft" =/yNp>fe#-=25 Ua4a̒}fyzoѷCZ@hl'`ݶ4 aUh&kݜv66"}'#@%ڜL0bAN cXILvqL~[J)aN®MS}y~ h״Gx ޠ kV7eKY=M y)GbV4Z#]WӴf&hg Q5eΎ Dd[򒧡F|m2-ZSLT3C "qx^3McjJɴ7ns\>(~N##M3x[ܘ9fL{#0g}pҳ׶õFx%8j9UQ%sշFiI@_/:7 25F=Ȫ t"B-L羼eKg[}_!;dZ43#U5ܧhb&GgsB6J'4lЋ-`'>Бby2=Wld!4 %|֕%_6_twHMU7C&j.#@բaӦViDL_=5)yr0ؘOqۅg<^Jx1Ӓ9BǐE<ώ-Qhe5*VxږAn3/&5SǧbAF*ao{sp+gSG `w~{!TxGF &[hP"A7NZq݋W(sM ]n4k"\3aɿöcFNySscctYҍ1;)Eee˟bV|^Lg.c)"$pI`0QT|PNuq~" !EYma|ce՝Ŏ0ElE;ʿUze#ׁ_asZƆHWlUKo&Q %ˁ23CX$ˊG8ݢԔW.hUX6*5OҘ1Ln qU>UݽeMXrhUir[0MAlqq~e8a WU Y ?MUd4ǟ5l\>u B ocO4Bߞ֞DaGIK]i=U{bp(͞:5)Յ?ox"s0e: _Iz*~@>B. j' qY0tQmFtzWT-)I&KFluxdWVlY;_{lGȺ)T&fhɈ"4PWȭG8~azhOX^Y$&X`W#X\ Ӹ1m\j y8WKvg_5ü`U(} \nz??*\)SBKuNf ~3ҁ⍙OَF\*Ʃg̳$Z˽7GndZU17hc *<sCB.xY_De821]ii#F C[kY! C.4}PŒhf.D =h@yctfdw J*=7DBZf jHYb !rV. QR82?IQ]nn5_#&ovu$Rt])OO.Ez[>/=%%g@] <'w]r||y X_O} t=!tIzL0-#Z[}۸SF,Yaɓu RGD&iJ `i3H)Q]tiz4y+[qR8j MG+@ei-OH6VU$a񰴜G'Vߋ=rkx,=IFh(W1F6"i$p͘B[w8Ccê6-m {c" /aeAecpReW,K(nR}IZ#R#rPw|l~/)#" ے|m3eV:U(jSs ›NqSj $, ŕsSOc=PA#pImLpfÈ}~lRrjcJ=NN<%!$dfc[>mmKW0 8AG{ kfFݮA͞<\[e~}E,"n.Ș 2XQ%ۭE+ xet,勒V@o8v"ye6k]HS<{l@4}NB^R2Y1.n <r!T[jHZ``N+S/0;jsvLΉ,7%XnLN.{'w %I^x`n@ǣ\5^/PGxdH&><π$ZW\9(l-h#bWD4%zW14FrYOe$hp fa~9Pc04 -+vbjM EXZ}\U#ӀTA}v8;$J>ZXB'M_ CTnml[U!ϖM8i9%562".`2wo(t;gٳU.`Q 6ZW%Ujv]6Me"&~qЫeV%H-ṣk >#j dA~'~((n=1%a3>qQNSn e[j o޼&,H/K֚PK|מE{Q8m\f"k ;Kbyb2fo[ o(\*ntĐilA1Z$UObLSSq@iOUƧ@7 D$A`JF0q@fM$9WHYp<8cAs;۵e#ȵ4 YѠrNBYOad6Ki~MO xHYE> շ>P 6-:mNЍ6H6_逯-tYgcAqJ!Azql~VLen.LAbf[咜NGyZg 7ZQ÷Q*@դ]QGLwccNL1=$ At47|sV|,[o-r)nĨ2C bʶ)-X;B_%0@ѦK>,`x@.]#ls\3sa=!IISƫiaS?ЧgI˃z /#L9U+P6՗EG%8ZY~v>r?OEۛbRxeE|)dNѝ„s̐!-ŭ WBw8Ȍzo wREG;qfo D'_wNj{*ܤHuhI"cJfγF`LyP|jʶ]hLƾ"&w{94Sϡf#|(.+|Yx@ nωT{t?Ciz'5q/$hO@Q7V&ԵDptr&]+o7`9 AYCg>Iڌ~*9ڽ8ˤM q'LzG. NI}lAlĩ%xG,v[Fʯ:!˥ ;M@1 !Xeg&L;. 6꼬73lf^.Ik;K5ŁuGDf oerD4A"' 7ȶ|5 W 5"ϫ6EĻuP%N8ԣ/̎X6Ly B9mg֞nsmKǾ)BV.TZJ X9=Ŵp@f%dHΦꆠ))=*ك?8NVH-gpIb4(|"xǍWb3eW)P|'<!|F["/K(,[ުdCS9$2˗Eq07GhT2f۝(\tm ؘ v[WwhEh,%Lz)y-QAȜ1: bKAYEI"ېMrMm##)-_xj\(/"-dwh'j^3iwRQ+c$ϡ8M7L72jmҗ/FegkMY4Ԑ\4B WLᓱ䜲Jهt)De1-dPq >7\uLO懥hb<ZuzYX")/Q>NYw-o̘ӚowTT}gt_Ll7ZUkɭb}(qA)eMe#xb*8ݗ·1$Xܠ70)B<oy`?kW|eF6e"8E@&aÎ##k2"dH_D>ǜ<٬ G9_RWO80ta=T2yN5Z;pszLZf ]K%XC`4`}[ $݄ɖ:,hyʿCjY f~Aߣy )nqrD]]PxvhP$.ء ať {F%ca'ϙ4pnrg[*xhB͔E`}WUVA[uO-Ẅ́|Zp8 Y%0NP|F^,s%ؼ :\#w*v~:V=C >fmGvHn0lמϺĝ;:bE&9i,"0X? /'Usq[eė\ tQv@>`cf <ɘ$ۄ1lK! bu=lMURi1fqE\3m-=AQQpY2dg9mVY9lhIjh ?|Fe^l⡉aVG=Z>BƈYVoE 8nz=*<5Ed@QLVvfmAviSccW~:eWPW|7FD^X.G5[ )jNop 5 :XU,\1]=H[0(=#|"q]L8Tr$bthbЋ ?>|l*Kw]R-M >5UCډR n*5$acJ tAdS-rah Vz9S)%LL0BsR]W ZP9TX_Ôp҇ުbx56ȗw<]Vg0*![T=Yhs͠ Z@S":Wէ$epb b`"A]n`sC0{/N+bm`5%Z>a|tJ,NVDӽ>o\%H;`f9Xv45ՊFA:u0*m3@Ž)=Q0/d<9}* 4kox'-MV?^}voKw E|wn<\deiy+} @\[ ci#aZ A2A< |6YߒMN k !:{$(f A5LDM*ѭ^̯C4W⧹v(F:8`'HA2:M+/O_(mjT@&|t0i,{ȅBe*\F6nw ~=R;YXdL+A.tqb|ѯp(S/VJV(xܘ\ k p͏ ?N}.8(?@J qܺNCE]Iy 8mAEH^1apɛ[Z8ASǏH3gP$mLH)H9E|lqqX: .(VV;G~L /g$gzѶ0rU-BB F"H##[ $DnߟJ헃4)FB%i;yB)erPȞ܏Jc BF3'xu{QEك/];MD-;NI|6{~mZ 3_,g8mhN" QM7ߵZ$ R#xBP1#=rs|rD,c"raT*׈icHOm>iDip̧oX&̶d+j;d52bI1ztbq4Ql "w5D˨(6 9 ;6TvX_QRX"6˚ldQ nv{,{g!z,ALlL#uybmt}/w^;@@Pmt t|uha|vTq9$Jo^\j[X*uU!! DDZqTŴ2[NJ&z1PH(:? F=S?(+N6N΢Gb$P}=Luq Ԉ;VѕɑFˤS}_9ӵMKDLS׻gu<"э*1tsFj$/gIq_*63] Dwv ;a'( Z 1HKEKh6B/Z) Gv‹υ|N%H_:ѐz|mCf@G-Kkkj~lp0+[2EkI4\_UL5mafE NJ$ywWJJDdlHeM?[^rU le6R4V8EnlڵO`Vl3 H55qj#L̪qA}XDwE1/rbX+=<Љ^< NHl Vm!nlY2\@s1z[Kp?Jz*8Zq&dvYVnSƟ|FRa1f]"o 7.9]z\6=2Ef% (̖F<kn˘Dp/H#Z|fسƵqx9iy Ha[8gfnCkድ=KI4hIϭXUsa1@*g>PUg(l,*8V7At(`J*K٬ [`+e&BY:پm=O,пԧk!?~RW#sVspy. 0+;c{8LaN):chwS9̓-)Nhg UPD ڄwwZA0RK6zU!_Tπ oPo2xfwI_<联i|XpGسuu=R.i fm=R^=йfwjg ,2 T/HðS yFI \S^nAo&Ζi3&/P'鏔ҁO]B "@XA2?k'Ԥь6 Y<\.2'E;"P3Ce皙s'ʶa;Ɠ6cT@jwE⟐?*ܲ-R}KBiR|[UVΰt~v-귏~̎ ]=$f@mʰڤV@3_/ f|!]~/턌"1z99H)[DQJ2٭'<+u`>y0 ap?cy6O.{: SU%cex7bC'\MXJOwf5z#Fu7z`:!|MbŚO;mV23tޜ2>?φ9=y!<8~ұa%'됆 1wQADb}( .Kz(c!۳{0"̾}6<ײ3GQAGd9^ˊ8x~=k<;_&A#iHKrV/` A)ps$ѨQ;e c׉yʳD-L6].>.}p2p9CƝt7jZ@+(sshz. M+#sq@OgWF?\X|vM~1:z2~NJf 3s>R r8^cSF) ,,~ؓrv ۿ"@[PHn|g.N@}>exx6pt)E\Ng|E(+;x{N,?J8K-_kX1b&| T}Z \C gE ^_JRMz \ W]l˛YieKGqGzm&xmv2xwNvH' "w A|dPnG1H#l` 0+Y0N΂U <;J4BكjSj ƒPBp܉b?1bJԋMوMI-u=5Prb[x[mrshV:胫n ӓWLX]h/*~mh²CCRL@ºF&Ӳ2c"QSہ-y^ߤc:aZ;TiOU2ԂOyJc10 2~}GVoA#q4Yto8`ax:t JWlo¡].!3{E)#Ў*FK2opL~6w* RG N,\qփ5.ŒIܒP(GF\ݟwyI DLYr-fW?3C@ZX\=zhȡ{xȡL}C4u]&Az`!DoZR KY1 ?ݦ1-V0vpru䶉Ƽ9$0AW0r %esG$vݞs@W,t71*yuT)2 ;/:e$ E2x:?c>*SƔ9+-'|/y/"ufQ8c0a*)5aN>}Wj@`5Z7~pهxC풨s5iz`N%:ArL(%^}qݏ8Eѕ6~w OVI rA Z})cr7©`f*lwƸkѶnW.[=A-'əLm_~\w\RO&#Uz:Nd2x,/(I>!cao= =8ӈ#[6lJIfۑC  =wLU='Rh fiۧ1'w _96l/'jMg"RWE,s:mz3/AHQp]{jty2MLW:pK+PPnrk+oCs>*3\yKkfE~=4 0b×%c9c$ K2PąͨTMC vx<$EOc|zE P;dZiplȇ./p [ qg28CWϳy0bHT<l#' bm 6lwr8J0QYg/BC9&D8i?GU $=8!e%Y6" Tg>3NR. 1 |ώS22 ŒT/pY `kJKX=\FCG+>c-]e-=XRmjK^Ϸ^H`;BIQًk*HMNsiUOCmI>1ӸPVc[a8c+'7oKP@dXS$g!Y /G m4S'wW T8UqEt4-2j:Ay*&fMӉG ݰ*6d]FK2U̺~h[ld P*jԙg)0& N46, g<5c;. gFԩ Il^FwY|>aM')H^50*Mѿ% nLVU_an7m-|M "#=C?#N2`xWQ%)1& ٷ-JAy:7S:σI (gIX:w}–9V%B3~|DA3#dw/%ە:Pkq>*_k܆f^ phPQ y\0.{϶xw[&58ώ[q`VZ&,M'gB=XmJr\4˜£JѺJF?C.k'Ű>@f1%xnMjΨ۪N3548F[U$QaF8yYA"" :)`9؏Z7-g p,Qkc],=X6Eۧo.7QO>:*։Gq3*FKxTZoa-4~uAҦXg禽Y7b 4SM L)'jjq/j! }}checkit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_65355_zeroedtags.tif000066400000000000000000030000421327425157300254450ustar00rootroot00000000000000II*&checkit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_count_is_zero.tiff000066400000000000000000000005031327425157300255560ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_incomplete.tif000066400000000000000000000000341327425157300246640ustar00rootroot00000000000000II*&checkit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_not_word_aligned.tif000066400000000000000000000005051327425157300260460ustar00rootroot00000000000000II*'   G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_points_outside_filesize.tif000066400000000000000000000005031327425157300274700ustar00rootroot00000000000000II*  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_IFD_with_endless_loop.tif000066400000000000000000000005031327425157300262470ustar00rootroot00000000000000II*&  G@(&T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_empty_IFD.tif000066400000000000000000000000641327425157300236660ustar00rootroot00000000000000II*&checkit_tiff-0.4.2/tiffs_should_fail/minimal_exifidf_offset_is_zero.tiff000066400000000000000000000006451327425157300267370ustar00rootroot00000000000000II* 4@(iT5T50230 01002016:12:01 00:00:00T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_invalid_type_imagewidth.tif000066400000000000000000000005031327425157300267350ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_offsets_are_zero.tiff000066400000000000000000000005031327425157300255510ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_offsets_multiple_stripoffsets.tif000066400000000000000000000005001327425157300302400ustar00rootroot00000000000000II*&   (T5T5 #checkit_tiff-0.4.2/tiffs_should_fail/minimal_offsets_multiple_used.tif000066400000000000000000000016261327425157300264570ustar00rootroot00000000000000II*b  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiff  G@ (T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiff   @4<(; T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffAnonymouscheckit_tiff-0.4.2/tiffs_should_fail/minimal_offsets_not_word_aligned.tif000066400000000000000000000005041327425157300271140ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tag_is_doubled.tif000066400000000000000000000005031327425157300250100ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tag_points_outside_filesize.tif000066400000000000000000000003741327425157300276470ustar00rootroot00000000000000II*&  G@(T5T5checkit_tiff-0.4.2/tiffs_should_fail/minimal_tag_with_ascii_with_multiple_zeros.tif000066400000000000000000000005031327425157300312120ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tifcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tag_with_ascii_without_byte_zero.tif000066400000000000000000000005031327425157300306670ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tifffminimal_tag_with_contradictory_photometricinterpretation_and_colortag.tiff000066400000000000000000000011711327425157300370300ustar00rootroot00000000000000checkit_tiff-0.4.2/tiffs_should_failII*D  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiff  G2@(@&T5T50mi w`/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tag_with_count_2M.tif000066400000000000000000000005031327425157300254200ustar00rootroot00000000000000II*&  @(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tag_with_count_equal_null.tif000066400000000000000000000005031327425157300273030ustar00rootroot00000000000000II*&  @(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_tags_in_wrong_order.tif000066400000000000000000000005031327425157300260770ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/minimal_without_IFD.tif000066400000000000000000000000101327425157300242220ustar00rootroot00000000000000II*checkit_tiff-0.4.2/tiffs_should_fail/minimal_wrong_exififd_type.tif000066400000000000000000000006451327425157300257460ustar00rootroot00000000000000II* 4@(i T5T50230 01002016:12:01 00:00:00T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/no_tiff/000077500000000000000000000000001327425157300212605ustar00rootroot00000000000000checkit_tiff-0.4.2/tiffs_should_fail/no_tiff/README.txt000066400000000000000000000004361327425157300227610ustar00rootroot00000000000000* minimal.jxr - JPEG XR, based on minimal_valid.tif created via GIMP plugin http://registry.gimp.org/node/25508 * minimal.mdi - Microsoft Image Document, based on minimal_valid.tif, only header is changed * minimal.tiff64 - BigTIFF, based on minimal_valid.tif created via libtiff tools checkit_tiff-0.4.2/tiffs_should_fail/no_tiff/minimal.jxr000066400000000000000000000003461327425157300234360ustar00rootroot00000000000000II $oNK=wv C C`WMPHOTOD ``!!0 =(]▶^I->gk-܇>^ˇ,checkit_tiff-0.4.2/tiffs_should_fail/no_tiff/minimal.mdi000066400000000000000000000005031327425157300233770ustar00rootroot00000000000000EP*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_fail/no_tiff/minimal.tiff64000066400000000000000000000005761327425157300237420ustar00rootroot00000000000000II+.pppp   T5T5()checkit_tiff-0.4.2/tiffs_should_fail/wrong_subfile_type__wrong_xresolution_alignment.tif000066400000000000000000000003611327425157300323320ustar00rootroot00000000000000II*& @(H0H0checkit_tiff-0.4.2/tiffs_should_pass/000077500000000000000000000000001327425157300176675ustar00rootroot00000000000000checkit_tiff-0.4.2/tiffs_should_pass/bigendian/000077500000000000000000000000001327425157300216075ustar00rootroot00000000000000checkit_tiff-0.4.2/tiffs_should_pass/bigendian/minimal_valid_baseline_BigEndian.tiff000066400000000000000000000003601327425157300310270ustar00rootroot00000000000000MM*& @(5T5Tcheckit_tiff-0.4.2/tiffs_should_pass/minimal_valid.tiff000066400000000000000000000005031327425157300233440ustar00rootroot00000000000000II*&  G@(T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_pass/minimal_valid_12bit.tiff000066400000000000000000000010121327425157300243410ustar00rootroot00000000000000II*4   ,()T5T5checkit_tiff-0.4.2/tiffs_should_pass/minimal_valid_16bit.tiff000066400000000000000000000011561327425157300243560ustar00rootroot00000000000000II*  ^f()T5T5checkit_tiff-0.4.2/tiffs_should_pass/minimal_valid_baseline.tiff000066400000000000000000000005031327425157300252060ustar00rootroot00000000000000II*& @(T5T5T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_pass/minimal_valid_multiple_stripoffsets.tif000066400000000000000000000005001327425157300277210ustar00rootroot00000000000000II*&   (T5T5  #checkit_tiff-0.4.2/tiffs_should_pass/minimal_valid_tiled.tiff000066400000000000000000000203361327425157300245330ustar00rootroot00000000000000II*    (BCDE T5T5checkit_tiff-0.4.2/tiffs_should_pass/minimal_valid_with_exif.tiff000066400000000000000000000006451327425157300254210ustar00rootroot00000000000000II* 4@(iT5T50230 01002016:12:01 00:00:00T5T5/home/romeyke/fixit_tiff/checkit/tiffs_should_pass/minimal_valid2.tiffcheckit_tiff-0.4.2/tiffs_should_pass/minimal_valid_with_icc.tiff000066400000000000000000000160221327425157300252200ustar00rootroot00000000000000II*&pppp   ()s T5T5 lcms0mntrRGB XYZ  acspMSFTlcms-lcms dmndjdeschdmddhwtptPrXYZdbXYZxgXYZrTRC gTRC  bTRC chrm$cprt!desclcms generated descsRGBdescsRGBXYZ =XYZ o8XYZ $XYZ bcurv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Kmcurv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Kmcurv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmchrmT{L&f\textno copyright, use freely